Compare commits
	
		
			5 Commits
		
	
	
		
			paultag/wa
			...
			refactor-l
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 2363010cbc | |||
| bd17bc98d5 | |||
| e7a2824cb2 | |||
| f77ed3d790 | |||
| bc5fdbad43 | 
| @ -12,7 +12,6 @@ | ||||
|     "@headlessui/tailwindcss": "^0.2.0", | ||||
|     "@kittycad/lib": "^0.0.67", | ||||
|     "@lezer/javascript": "^1.4.9", | ||||
|     "@open-rpc/client-js": "^1.8.1", | ||||
|     "@react-hook/resize-observer": "^2.0.1", | ||||
|     "@replit/codemirror-interact": "^6.3.1", | ||||
|     "@tauri-apps/api": "2.0.0-beta.12", | ||||
| @ -42,7 +41,7 @@ | ||||
|     "fuse.js": "^7.0.0", | ||||
|     "html2canvas-pro": "^1.4.3", | ||||
|     "http-server": "^14.1.1", | ||||
|     "json-rpc-2.0": "^1.6.0", | ||||
|     "json-rpc-2.0": "^1.7.0", | ||||
|     "jszip": "^3.10.1", | ||||
|     "node-fetch": "^3.3.2", | ||||
|     "re-resizable": "^6.9.11", | ||||
| @ -62,7 +61,8 @@ | ||||
|     "ua-parser-js": "^1.0.37", | ||||
|     "uuid": "^9.0.1", | ||||
|     "vitest": "^1.6.0", | ||||
|     "vscode-jsonrpc": "^8.2.1", | ||||
|     "vscode-languageclient": "^9.0.1", | ||||
|     "vscode-languageserver": "^9.0.1", | ||||
|     "vscode-languageserver-protocol": "^3.17.5", | ||||
|     "wasm-pack": "^0.12.1", | ||||
|     "web-vitals": "^3.5.2", | ||||
|  | ||||
| @ -7,8 +7,7 @@ import React, { | ||||
|   useContext, | ||||
|   useState, | ||||
| } from 'react' | ||||
| import { FromServer, IntoServer } from 'editor/plugins/lsp/codec' | ||||
| import Client from '../editor/plugins/lsp/client' | ||||
| import LspServerClient from '../editor/plugins/lsp/client' | ||||
| import { TEST, VITE_KC_API_BASE_URL } from 'env' | ||||
| import kclLanguage from 'editor/plugins/lsp/kcl/language' | ||||
| import { copilotPlugin } from 'editor/plugins/lsp/copilot' | ||||
| @ -19,9 +18,7 @@ import { LanguageSupport } from '@codemirror/language' | ||||
| import { useNavigate } from 'react-router-dom' | ||||
| import { paths } from 'lib/paths' | ||||
| import { FileEntry } from 'lib/types' | ||||
| import Worker from 'editor/plugins/lsp/worker.ts?worker' | ||||
| import { | ||||
|   LspWorkerEventType, | ||||
|   KclWorkerOptions, | ||||
|   CopilotWorkerOptions, | ||||
|   LspWorker, | ||||
| @ -30,7 +27,6 @@ import { wasmUrl } from 'lang/wasm' | ||||
| import { PROJECT_ENTRYPOINT } from 'lib/constants' | ||||
| import { useNetworkContext } from 'hooks/useNetworkContext' | ||||
| import { NetworkHealthState } from 'hooks/useNetworkStatus' | ||||
| import { err, trap } from 'lib/trap' | ||||
|  | ||||
| function getWorkspaceFolders(): LSP.WorkspaceFolder[] { | ||||
|   return [] | ||||
| @ -107,32 +103,23 @@ export const LspProvider = ({ children }: { children: React.ReactNode }) => { | ||||
|       return { lspClient: null } | ||||
|     } | ||||
|  | ||||
|     const lspWorker = new Worker({ name: 'kcl' }) | ||||
|     const initEvent: KclWorkerOptions = { | ||||
|       wasmUrl: wasmUrl(), | ||||
|     const options: KclWorkerOptions = { | ||||
|       token: token, | ||||
|       baseUnit: defaultUnit.current, | ||||
|       apiBaseUrl: VITE_KC_API_BASE_URL, | ||||
|       callback: () => { | ||||
|         setIsLspReady(true) | ||||
|       }, | ||||
|       wasmUrl: wasmUrl(), | ||||
|     } | ||||
|     lspWorker.postMessage({ | ||||
|       worker: LspWorker.Kcl, | ||||
|       eventType: LspWorkerEventType.Init, | ||||
|       eventData: initEvent, | ||||
|  | ||||
|     const lsp = new LspServerClient({ worker: LspWorker.Kcl, options }) | ||||
|     lsp.startServer() | ||||
|  | ||||
|     const lspClient = new LanguageServerClient({ | ||||
|       client: lsp, | ||||
|       name: LspWorker.Kcl, | ||||
|     }) | ||||
|     lspWorker.onmessage = function (e) { | ||||
|       if (err(fromServer)) return | ||||
|       fromServer.add(e.data) | ||||
|     } | ||||
|  | ||||
|     const intoServer: IntoServer = new IntoServer(LspWorker.Kcl, lspWorker) | ||||
|     const fromServer: FromServer | Error = FromServer.create() | ||||
|     if (err(fromServer)) return { lspClient: null } | ||||
|  | ||||
|     const client = new Client(fromServer, intoServer) | ||||
|  | ||||
|     setIsLspReady(true) | ||||
|  | ||||
|     const lspClient = new LanguageServerClient({ client, name: LspWorker.Kcl }) | ||||
|     return { lspClient } | ||||
|   }, [ | ||||
|     // We need a token for authenticating the server. | ||||
| @ -185,32 +172,19 @@ export const LspProvider = ({ children }: { children: React.ReactNode }) => { | ||||
|       return { lspClient: null } | ||||
|     } | ||||
|  | ||||
|     const lspWorker = new Worker({ name: 'copilot' }) | ||||
|     const initEvent: CopilotWorkerOptions = { | ||||
|       wasmUrl: wasmUrl(), | ||||
|     const options: CopilotWorkerOptions = { | ||||
|       token: token, | ||||
|       apiBaseUrl: VITE_KC_API_BASE_URL, | ||||
|       callback: () => { | ||||
|         setIsCopilotReady(true) | ||||
|       }, | ||||
|       wasmUrl: wasmUrl(), | ||||
|     } | ||||
|     lspWorker.postMessage({ | ||||
|       worker: LspWorker.Copilot, | ||||
|       eventType: LspWorkerEventType.Init, | ||||
|       eventData: initEvent, | ||||
|     }) | ||||
|     lspWorker.onmessage = function (e) { | ||||
|       if (err(fromServer)) return | ||||
|       fromServer.add(e.data) | ||||
|     } | ||||
|  | ||||
|     const intoServer: IntoServer = new IntoServer(LspWorker.Copilot, lspWorker) | ||||
|     const fromServer: FromServer | Error = FromServer.create() | ||||
|     if (err(fromServer)) return { lspClient: null } | ||||
|  | ||||
|     const client = new Client(fromServer, intoServer) | ||||
|  | ||||
|     setIsCopilotReady(true) | ||||
|     const lsp = new LspServerClient({ worker: LspWorker.Copilot, options }) | ||||
|     lsp.startServer() | ||||
|  | ||||
|     const lspClient = new LanguageServerClient({ | ||||
|       client, | ||||
|       client: lsp, | ||||
|       name: LspWorker.Copilot, | ||||
|     }) | ||||
|     return { lspClient } | ||||
|  | ||||
| @ -1,197 +1,54 @@ | ||||
| import * as jsrpc from 'json-rpc-2.0' | ||||
| import * as LSP from 'vscode-languageserver-protocol' | ||||
|  | ||||
| import { LspContext, LspWorkerEventType } from './types' | ||||
| import { | ||||
|   registerServerCapability, | ||||
|   unregisterServerCapability, | ||||
| } from './server-capability-registration' | ||||
| import { Codec, FromServer, IntoServer } from './codec' | ||||
| import { err } from 'lib/trap' | ||||
|   LanguageClient, | ||||
|   LanguageClientOptions, | ||||
| } from 'vscode-languageclient/browser' | ||||
| import Worker from 'editor/plugins/lsp/worker.ts?worker' | ||||
|  | ||||
| const client_capabilities: LSP.ClientCapabilities = { | ||||
|   textDocument: { | ||||
|     hover: { | ||||
|       dynamicRegistration: true, | ||||
|       contentFormat: ['plaintext', 'markdown'], | ||||
|     }, | ||||
|     moniker: {}, | ||||
|     synchronization: { | ||||
|       dynamicRegistration: true, | ||||
|       willSave: false, | ||||
|       didSave: false, | ||||
|       willSaveWaitUntil: false, | ||||
|     }, | ||||
|     completion: { | ||||
|       dynamicRegistration: true, | ||||
|       completionItem: { | ||||
|         snippetSupport: false, | ||||
|         commitCharactersSupport: true, | ||||
|         documentationFormat: ['plaintext', 'markdown'], | ||||
|         deprecatedSupport: false, | ||||
|         preselectSupport: false, | ||||
|       }, | ||||
|       contextSupport: false, | ||||
|     }, | ||||
|     signatureHelp: { | ||||
|       dynamicRegistration: true, | ||||
|       signatureInformation: { | ||||
|         documentationFormat: ['plaintext', 'markdown'], | ||||
|       }, | ||||
|     }, | ||||
|     declaration: { | ||||
|       dynamicRegistration: true, | ||||
|       linkSupport: true, | ||||
|     }, | ||||
|     definition: { | ||||
|       dynamicRegistration: true, | ||||
|       linkSupport: true, | ||||
|     }, | ||||
|     typeDefinition: { | ||||
|       dynamicRegistration: true, | ||||
|       linkSupport: true, | ||||
|     }, | ||||
|     implementation: { | ||||
|       dynamicRegistration: true, | ||||
|       linkSupport: true, | ||||
|     }, | ||||
|   }, | ||||
|   workspace: { | ||||
|     didChangeConfiguration: { | ||||
|       dynamicRegistration: true, | ||||
|     }, | ||||
|   }, | ||||
| } | ||||
| export default class LspServerClient { | ||||
|   context: LspContext | ||||
|   client: LanguageClient | null = null | ||||
|   worker: Worker | null = null | ||||
|  | ||||
| export default class Client extends jsrpc.JSONRPCServerAndClient { | ||||
|   afterInitializedHooks: (() => Promise<void>)[] = [] | ||||
|   #fromServer: FromServer | ||||
|   private serverCapabilities: LSP.ServerCapabilities<any> = {} | ||||
|   private notifyFn: ((message: LSP.NotificationMessage) => void) | null = null | ||||
|  | ||||
|   constructor(fromServer: FromServer, intoServer: IntoServer) { | ||||
|     super( | ||||
|       new jsrpc.JSONRPCServer(), | ||||
|       new jsrpc.JSONRPCClient(async (json: jsrpc.JSONRPCRequest) => { | ||||
|         const encoded = Codec.encode(json) | ||||
|         intoServer.enqueue(encoded) | ||||
|         if (null != json.id) { | ||||
|           // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||||
|           const response = await fromServer.responses.get(json.id) | ||||
|           this.client.receive(response as jsrpc.JSONRPCResponse) | ||||
|         } | ||||
|       }) | ||||
|     ) | ||||
|     this.#fromServer = fromServer | ||||
|   constructor(context: LspContext) { | ||||
|     this.context = context | ||||
|   } | ||||
|  | ||||
|   async start(): Promise<void> { | ||||
|     // process "window/logMessage": client <- server | ||||
|     this.addMethod(LSP.LogMessageNotification.type.method, (params) => { | ||||
|       const { type, message } = params as { | ||||
|         type: LSP.MessageType | ||||
|         message: string | ||||
|       } | ||||
|       let messageString = '' | ||||
|       switch (type) { | ||||
|         case LSP.MessageType.Error: { | ||||
|           messageString += '[error] ' | ||||
|           break | ||||
|         } | ||||
|         case LSP.MessageType.Warning: { | ||||
|           messageString += ' [warn] ' | ||||
|           break | ||||
|         } | ||||
|         case LSP.MessageType.Info: { | ||||
|           messageString += ' [info] ' | ||||
|           break | ||||
|         } | ||||
|         case LSP.MessageType.Log: { | ||||
|           messageString += '  [log] ' | ||||
|           break | ||||
|         } | ||||
|       } | ||||
|       // eslint-disable-next-line @typescript-eslint/no-unused-vars | ||||
|       messageString += message | ||||
|   async startServer() { | ||||
|     this.worker = new Worker({ name: this.context.worker }) | ||||
|     this.worker.postMessage({ | ||||
|       worker: this.context.worker, | ||||
|       eventType: LspWorkerEventType.Init, | ||||
|       eventData: this.context.options, | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   async startClient() { | ||||
|     const clientOptions: LanguageClientOptions = { | ||||
|       documentSelector: [{ language: 'kcl' }], | ||||
|       diagnosticCollectionName: 'markers', | ||||
|     } | ||||
|  | ||||
|     if (!this.worker) { | ||||
|       console.error('Worker not initialized') | ||||
|       return | ||||
|     }) | ||||
|     } | ||||
|  | ||||
|     // process "client/registerCapability": client <- server | ||||
|     this.addMethod(LSP.RegistrationRequest.type.method, (params) => { | ||||
|       // Register a server capability. | ||||
|       params.registrations.forEach( | ||||
|         (capabilityRegistration: LSP.Registration) => { | ||||
|           const caps = registerServerCapability( | ||||
|             this.serverCapabilities, | ||||
|             capabilityRegistration | ||||
|           ) | ||||
|           if (err(caps)) return (this.serverCapabilities = {}) | ||||
|           this.serverCapabilities = caps | ||||
|         } | ||||
|       ) | ||||
|     }) | ||||
|  | ||||
|     // process "client/unregisterCapability": client <- server | ||||
|     this.addMethod(LSP.UnregistrationRequest.type.method, (params) => { | ||||
|       // Unregister a server capability. | ||||
|       params.unregisterations.forEach( | ||||
|         (capabilityUnregistration: LSP.Unregistration) => { | ||||
|           const caps = unregisterServerCapability( | ||||
|             this.serverCapabilities, | ||||
|             capabilityUnregistration | ||||
|           ) | ||||
|           if (err(caps)) return (this.serverCapabilities = {}) | ||||
|           this.serverCapabilities = caps | ||||
|         } | ||||
|       ) | ||||
|     }) | ||||
|  | ||||
|     // request "initialize": client <-> server | ||||
|     const { capabilities } = await this.request( | ||||
|       LSP.InitializeRequest.type.method, | ||||
|       { | ||||
|         processId: null, | ||||
|         clientInfo: { | ||||
|           name: 'kcl-language-client', | ||||
|         }, | ||||
|         capabilities: client_capabilities, | ||||
|         rootUri: null, | ||||
|       } as LSP.InitializeParams | ||||
|     this.client = new LanguageClient( | ||||
|       this.context.worker + 'LspClient', | ||||
|       this.context.worker + ' LSP Client', | ||||
|       clientOptions, | ||||
|       this.worker | ||||
|     ) | ||||
|  | ||||
|     this.serverCapabilities = capabilities | ||||
|  | ||||
|     // notify "initialized": client --> server | ||||
|     this.notify(LSP.InitializedNotification.type.method, {}) | ||||
|  | ||||
|     await Promise.all( | ||||
|       this.afterInitializedHooks.map((f: () => Promise<void>) => f()) | ||||
|     ) | ||||
|     await Promise.all([this.processNotifications(), this.processRequests()]) | ||||
|   } | ||||
|  | ||||
|   getServerCapabilities(): LSP.ServerCapabilities<any> { | ||||
|     return this.serverCapabilities | ||||
|   } | ||||
|  | ||||
|   setNotifyFn(fn: (message: LSP.NotificationMessage) => void): void { | ||||
|     this.notifyFn = fn | ||||
|   } | ||||
|  | ||||
|   async processNotifications(): Promise<void> { | ||||
|     for await (const notification of this.#fromServer.notifications) { | ||||
|       if (this.notifyFn) { | ||||
|         this.notifyFn(notification) | ||||
|       } | ||||
|     try { | ||||
|       await this.client.start() | ||||
|     } catch (error) { | ||||
|       this.client.error(`Start failed`, error, 'force') | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   async processRequests(): Promise<void> { | ||||
|     for await (const request of this.#fromServer.requests) { | ||||
|       await this.receiveAndSend(request) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   pushAfterInitializeHook(...hooks: (() => Promise<void>)[]): void { | ||||
|     this.afterInitializedHooks.push(...hooks) | ||||
|   deactivate() { | ||||
|     return this.client?.stop() | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -1,79 +0,0 @@ | ||||
| import * as jsrpc from 'json-rpc-2.0' | ||||
| import * as vsrpc from 'vscode-jsonrpc' | ||||
|  | ||||
| import Bytes from './codec/bytes' | ||||
| import StreamDemuxer from './codec/demuxer' | ||||
| import Headers from './codec/headers' | ||||
| import Queue from './codec/queue' | ||||
| import Tracer from './tracer' | ||||
| import { LspWorkerEventType, LspWorker } from './types' | ||||
|  | ||||
| export const encoder = new TextEncoder() | ||||
| export const decoder = new TextDecoder() | ||||
|  | ||||
| export class Codec { | ||||
|   static encode( | ||||
|     json: jsrpc.JSONRPCRequest | jsrpc.JSONRPCResponse | ||||
|   ): Uint8Array { | ||||
|     const message = JSON.stringify(json) | ||||
|     const delimited = Headers.add(message) | ||||
|     return Bytes.encode(delimited) | ||||
|   } | ||||
|  | ||||
|   static decode<T>(data: Uint8Array): T { | ||||
|     const delimited = Bytes.decode(data) | ||||
|     const message = Headers.remove(delimited) | ||||
|     return JSON.parse(message) as T | ||||
|   } | ||||
| } | ||||
|  | ||||
| // FIXME: tracing efficiency | ||||
| export class IntoServer | ||||
|   extends Queue<Uint8Array> | ||||
|   implements AsyncGenerator<Uint8Array, never, void> | ||||
| { | ||||
|   private worker: Worker | null = null | ||||
|   private type_: LspWorker | null = null | ||||
|   constructor(type_?: LspWorker, worker?: Worker) { | ||||
|     super() | ||||
|     if (worker && type_) { | ||||
|       this.worker = worker | ||||
|       this.type_ = type_ | ||||
|     } | ||||
|   } | ||||
|   enqueue(item: Uint8Array): void { | ||||
|     Tracer.client(Headers.remove(decoder.decode(item))) | ||||
|     if (this.worker) { | ||||
|       this.worker.postMessage({ | ||||
|         worker: this.type_, | ||||
|         eventType: LspWorkerEventType.Call, | ||||
|         eventData: item, | ||||
|       }) | ||||
|     } else { | ||||
|       super.enqueue(item) | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| export interface FromServer extends WritableStream<Uint8Array> { | ||||
|   readonly responses: { | ||||
|     get(key: number | string): null | Promise<vsrpc.ResponseMessage> | ||||
|   } | ||||
|   readonly notifications: AsyncGenerator<vsrpc.NotificationMessage, never, void> | ||||
|   readonly requests: AsyncGenerator<vsrpc.RequestMessage, never, void> | ||||
|  | ||||
|   add(item: Uint8Array): void | ||||
| } | ||||
|  | ||||
| // eslint-disable-next-line @typescript-eslint/no-namespace | ||||
| export namespace FromServer { | ||||
|   export function create(): FromServer | Error { | ||||
|     // Calls private method .start() which can throw. | ||||
|     // This is an odd one of the bunch but try/catch seems most suitable here. | ||||
|     try { | ||||
|       return new StreamDemuxer() | ||||
|     } catch (e: any) { | ||||
|       return e | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -1,27 +0,0 @@ | ||||
| import { encoder, decoder } from '../codec' | ||||
|  | ||||
| export default class Bytes { | ||||
|   static encode(input: string): Uint8Array { | ||||
|     return encoder.encode(input) | ||||
|   } | ||||
|  | ||||
|   static decode(input: Uint8Array): string { | ||||
|     return decoder.decode(input) | ||||
|   } | ||||
|  | ||||
|   static append< | ||||
|     T extends { length: number; set(arr: T, offset: number): void } | ||||
|   >(constructor: { new (length: number): T }, ...arrays: T[]) { | ||||
|     let totalLength = 0 | ||||
|     for (const arr of arrays) { | ||||
|       totalLength += arr.length | ||||
|     } | ||||
|     const result = new constructor(totalLength) | ||||
|     let offset = 0 | ||||
|     for (const arr of arrays) { | ||||
|       result.set(arr, offset) | ||||
|       offset += arr.length | ||||
|     } | ||||
|     return result | ||||
|   } | ||||
| } | ||||
| @ -1,101 +0,0 @@ | ||||
| import * as vsrpc from 'vscode-jsonrpc' | ||||
|  | ||||
| import Bytes from './bytes' | ||||
| import PromiseMap from './map' | ||||
| import Queue from './queue' | ||||
| import Tracer from '../tracer' | ||||
| import { Codec } from '../codec' | ||||
|  | ||||
| export default class StreamDemuxer extends Queue<Uint8Array> { | ||||
|   readonly responses: PromiseMap<number | string, vsrpc.ResponseMessage> = | ||||
|     new PromiseMap() | ||||
|   readonly notifications: Queue<vsrpc.NotificationMessage> = | ||||
|     new Queue<vsrpc.NotificationMessage>() | ||||
|   readonly requests: Queue<vsrpc.RequestMessage> = | ||||
|     new Queue<vsrpc.RequestMessage>() | ||||
|  | ||||
|   readonly #start: Promise<void> | ||||
|  | ||||
|   constructor() { | ||||
|     super() | ||||
|     this.#start = this.start() | ||||
|   } | ||||
|  | ||||
|   private async start(): Promise<void> { | ||||
|     let contentLength: null | number = null | ||||
|     let buffer = new Uint8Array() | ||||
|  | ||||
|     for await (const bytes of this) { | ||||
|       buffer = Bytes.append(Uint8Array, buffer, bytes) | ||||
|       while (buffer.length > 0) { | ||||
|         // check if the content length is known | ||||
|         if (null == contentLength) { | ||||
|           // if not, try to match the prefixed headers | ||||
|           const match = Bytes.decode(buffer).match( | ||||
|             /^Content-Length:\s*(\d+)\s*/ | ||||
|           ) | ||||
|           if (null == match) continue | ||||
|  | ||||
|           // try to parse the content-length from the headers | ||||
|           const length = parseInt(match[1]) | ||||
|  | ||||
|           if (isNaN(length)) | ||||
|             return Promise.reject(new Error('invalid content length')) | ||||
|  | ||||
|           // slice the headers since we now have the content length | ||||
|           buffer = buffer.slice(match[0].length) | ||||
|  | ||||
|           // set the content length | ||||
|           contentLength = length | ||||
|         } | ||||
|  | ||||
|         // if the buffer doesn't contain a full message; await another iteration | ||||
|         if (buffer.length < contentLength) continue | ||||
|  | ||||
|         // Get just the slice of the buffer that is our content length. | ||||
|         const slice = buffer.slice(0, contentLength) | ||||
|  | ||||
|         // decode buffer to a string | ||||
|         const delimited = Bytes.decode(slice) | ||||
|  | ||||
|         // reset the buffer | ||||
|         buffer = buffer.slice(contentLength) | ||||
|         // reset the contentLength | ||||
|         contentLength = null | ||||
|  | ||||
|         const message = JSON.parse(delimited) as vsrpc.Message | ||||
|         Tracer.server(message) | ||||
|  | ||||
|         // demux the message stream | ||||
|         if (vsrpc.Message.isResponse(message) && null != message.id) { | ||||
|           this.responses.set(message.id, message) | ||||
|           continue | ||||
|         } | ||||
|         if (vsrpc.Message.isNotification(message)) { | ||||
|           this.notifications.enqueue(message) | ||||
|           continue | ||||
|         } | ||||
|         if (vsrpc.Message.isRequest(message)) { | ||||
|           this.requests.enqueue(message) | ||||
|           continue | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   add(bytes: Uint8Array): void { | ||||
|     const message = Codec.decode(bytes) as vsrpc.Message | ||||
|     Tracer.server(message) | ||||
|  | ||||
|     // demux the message stream | ||||
|     if (vsrpc.Message.isResponse(message) && null != message.id) { | ||||
|       this.responses.set(message.id, message) | ||||
|     } | ||||
|     if (vsrpc.Message.isNotification(message)) { | ||||
|       this.notifications.enqueue(message) | ||||
|     } | ||||
|     if (vsrpc.Message.isRequest(message)) { | ||||
|       this.requests.enqueue(message) | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -1,9 +0,0 @@ | ||||
| export default class Headers { | ||||
|   static add(message: string): string { | ||||
|     return `Content-Length: ${message.length}\r\n\r\n${message}` | ||||
|   } | ||||
|  | ||||
|   static remove(delimited: string): string { | ||||
|     return delimited.replace(/^Content-Length:\s*\d+\s*/, '') | ||||
|   } | ||||
| } | ||||
| @ -1,72 +0,0 @@ | ||||
| export default class PromiseMap<K, V extends { toString(): string }> { | ||||
|   #map: Map<K, PromiseMap.Entry<V>> = new Map() | ||||
|  | ||||
|   get(key: K & { toString(): string }): null | Promise<V> { | ||||
|     let initialized: PromiseMap.Entry<V> | ||||
|     // if the entry doesn't exist, set it | ||||
|     if (!this.#map.has(key)) { | ||||
|       initialized = this.#set(key) | ||||
|     } else { | ||||
|       // otherwise return the entry | ||||
|       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||||
|       initialized = this.#map.get(key)! | ||||
|     } | ||||
|     // if the entry is a pending promise, return it | ||||
|     if (initialized.status === 'pending') { | ||||
|       return initialized.promise | ||||
|     } else { | ||||
|       // otherwise return null | ||||
|       return null | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   #set(key: K, value?: V): PromiseMap.Entry<V> { | ||||
|     if (this.#map.has(key)) { | ||||
|       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||||
|       return this.#map.get(key)! | ||||
|     } | ||||
|     // placeholder resolver for entry | ||||
|     let resolve = (item: V) => { | ||||
|       void item | ||||
|     } | ||||
|     // promise for entry (which assigns the resolver | ||||
|     const promise = new Promise<V>((resolver) => { | ||||
|       resolve = resolver | ||||
|     }) | ||||
|     // the initialized entry | ||||
|     const initialized: PromiseMap.Entry<V> = { | ||||
|       status: 'pending', | ||||
|       resolve, | ||||
|       promise, | ||||
|     } | ||||
|     if (null != value) { | ||||
|       initialized.resolve(value) | ||||
|     } | ||||
|     // set the entry | ||||
|     this.#map.set(key, initialized) | ||||
|     return initialized | ||||
|   } | ||||
|  | ||||
|   set(key: K & { toString(): string }, value: V): this { | ||||
|     const initialized = this.#set(key, value) | ||||
|     // if the promise is pending ... | ||||
|     if (initialized.status === 'pending') { | ||||
|       // ... set the entry status to resolved to free the promise | ||||
|       this.#map.set(key, { status: 'resolved' }) | ||||
|       // ... and resolve the promise with the given value | ||||
|       initialized.resolve(value) | ||||
|     } | ||||
|     return this | ||||
|   } | ||||
|  | ||||
|   get size(): number { | ||||
|     return this.#map.size | ||||
|   } | ||||
| } | ||||
|  | ||||
| // eslint-disable-next-line @typescript-eslint/no-namespace | ||||
| export namespace PromiseMap { | ||||
|   export type Entry<V> = | ||||
|     | { status: 'pending'; resolve: (item: V) => void; promise: Promise<V> } | ||||
|     | { status: 'resolved' } | ||||
| } | ||||
| @ -1,6 +1,5 @@ | ||||
| import type * as LSP from 'vscode-languageserver-protocol' | ||||
| import Client from './client' | ||||
| import { SemanticToken, deserializeTokens } from './kcl/semantic_tokens' | ||||
| import LspServerClient from './client' | ||||
| import { LanguageServerPlugin } from 'editor/plugins/lsp/plugin' | ||||
| import { CopilotLspCompletionParams } from 'wasm-lib/kcl/bindings/CopilotLspCompletionParams' | ||||
| import { CopilotCompletionResponse } from 'wasm-lib/kcl/bindings/CopilotCompletionResponse' | ||||
| @ -10,7 +9,7 @@ import { UpdateUnitsParams } from 'wasm-lib/kcl/bindings/UpdateUnitsParams' | ||||
| import { UpdateCanExecuteParams } from 'wasm-lib/kcl/bindings/UpdateCanExecuteParams' | ||||
| import { UpdateUnitsResponse } from 'wasm-lib/kcl/bindings/UpdateUnitsResponse' | ||||
| import { UpdateCanExecuteResponse } from 'wasm-lib/kcl/bindings/UpdateCanExecuteResponse' | ||||
| import { LspWorker } from './types' | ||||
| import { LspWorker } from 'editor/plugins/lsp/types' | ||||
|  | ||||
| // https://microsoft.github.io/language-server-protocol/specifications/specification-current/ | ||||
|  | ||||
| @ -54,7 +53,7 @@ interface LSPNotifyMap { | ||||
| } | ||||
|  | ||||
| export interface LanguageServerClientOptions { | ||||
|   client: Client | ||||
|   client: LspServerClient | ||||
|   name: LspWorker | ||||
| } | ||||
|  | ||||
| @ -67,7 +66,7 @@ export interface LanguageServerOptions { | ||||
| } | ||||
|  | ||||
| export class LanguageServerClient { | ||||
|   private client: Client | ||||
|   private client: LspServerClient | ||||
|   readonly name: string | ||||
|  | ||||
|   public ready: boolean | ||||
| @ -77,7 +76,8 @@ export class LanguageServerClient { | ||||
|   public initializePromise: Promise<void> | ||||
|  | ||||
|   private isUpdatingSemanticTokens: boolean = false | ||||
|   private semanticTokens: SemanticToken[] = [] | ||||
|   // tODO: Fix this type | ||||
|   private semanticTokens: any = {} | ||||
|   private queuedUids: string[] = [] | ||||
|  | ||||
|   constructor(options: LanguageServerClientOptions) { | ||||
| @ -93,8 +93,7 @@ export class LanguageServerClient { | ||||
|  | ||||
|   async initialize() { | ||||
|     // Start the client in the background. | ||||
|     this.client.setNotifyFn(this.processNotifications.bind(this)) | ||||
|     this.client.start() | ||||
|     this.client.startClient() | ||||
|  | ||||
|     this.ready = true | ||||
|   } | ||||
| @ -103,10 +102,6 @@ export class LanguageServerClient { | ||||
|     return this.name | ||||
|   } | ||||
|  | ||||
|   getServerCapabilities(): LSP.ServerCapabilities<any> { | ||||
|     return this.client.getServerCapabilities() | ||||
|   } | ||||
|  | ||||
|   close() {} | ||||
|  | ||||
|   textDocumentDidOpen(params: LSP.DidOpenTextDocumentParams) { | ||||
| @ -117,13 +112,10 @@ export class LanguageServerClient { | ||||
|       plugin.documentUri = params.textDocument.uri | ||||
|       plugin.languageId = params.textDocument.languageId | ||||
|     } | ||||
|  | ||||
|     this.updateSemanticTokens(params.textDocument.uri) | ||||
|   } | ||||
|  | ||||
|   textDocumentDidChange(params: LSP.DidChangeTextDocumentParams) { | ||||
|     this.notify('textDocument/didChange', params) | ||||
|     this.updateSemanticTokens(params.textDocument.uri) | ||||
|   } | ||||
|  | ||||
|   textDocumentDidClose(params: LSP.DidCloseTextDocumentParams) { | ||||
| @ -160,64 +152,19 @@ export class LanguageServerClient { | ||||
|     this.notify('workspace/didDeleteFiles', params) | ||||
|   } | ||||
|  | ||||
|   async updateSemanticTokens(uri: string) { | ||||
|     const serverCapabilities = this.getServerCapabilities() | ||||
|     if (!serverCapabilities.semanticTokensProvider) { | ||||
|       return | ||||
|     } | ||||
|  | ||||
|     // Make sure we can only run, if we aren't already running. | ||||
|     if (!this.isUpdatingSemanticTokens) { | ||||
|       this.isUpdatingSemanticTokens = true | ||||
|  | ||||
|       const result = await this.request('textDocument/semanticTokens/full', { | ||||
|         textDocument: { | ||||
|           uri, | ||||
|         }, | ||||
|       }) | ||||
|  | ||||
|       this.semanticTokens = await deserializeTokens( | ||||
|         result.data, | ||||
|         this.getServerCapabilities().semanticTokensProvider | ||||
|       ) | ||||
|  | ||||
|       this.isUpdatingSemanticTokens = false | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   getSemanticTokens(): SemanticToken[] { | ||||
|     return this.semanticTokens | ||||
|   } | ||||
|  | ||||
|   async textDocumentHover(params: LSP.HoverParams) { | ||||
|     const serverCapabilities = this.getServerCapabilities() | ||||
|     if (!serverCapabilities.hoverProvider) { | ||||
|       return | ||||
|     } | ||||
|     return await this.request('textDocument/hover', params) | ||||
|   } | ||||
|  | ||||
|   async textDocumentFormatting(params: LSP.DocumentFormattingParams) { | ||||
|     const serverCapabilities = this.getServerCapabilities() | ||||
|     if (!serverCapabilities.documentFormattingProvider) { | ||||
|       return | ||||
|     } | ||||
|     return await this.request('textDocument/formatting', params) | ||||
|   } | ||||
|  | ||||
|   async textDocumentFoldingRange(params: LSP.FoldingRangeParams) { | ||||
|     const serverCapabilities = this.getServerCapabilities() | ||||
|     if (!serverCapabilities.foldingRangeProvider) { | ||||
|       return | ||||
|     } | ||||
|     return await this.request('textDocument/foldingRange', params) | ||||
|   } | ||||
|  | ||||
|   async textDocumentCompletion(params: LSP.CompletionParams) { | ||||
|     const serverCapabilities = this.getServerCapabilities() | ||||
|     if (!serverCapabilities.completionProvider) { | ||||
|       return | ||||
|     } | ||||
|     const response = await this.request('textDocument/completion', params) | ||||
|     return response | ||||
|   } | ||||
| @ -236,14 +183,19 @@ export class LanguageServerClient { | ||||
|     method: K, | ||||
|     params: LSPRequestMap[K][0] | ||||
|   ): Promise<LSPRequestMap[K][1]> { | ||||
|     return this.client.request(method, params) as Promise<LSPRequestMap[K][1]> | ||||
|     return this.client.client?.sendRequest(method, params) as Promise< | ||||
|       LSPRequestMap[K][1] | ||||
|     > | ||||
|   } | ||||
|  | ||||
|   private notify<K extends keyof LSPNotifyMap>( | ||||
|     method: K, | ||||
|     params: LSPNotifyMap[K] | ||||
|   ): void { | ||||
|     return this.client.notify(method, params) | ||||
|   ): Promise<void> { | ||||
|     if (!this.client.client) { | ||||
|       return Promise.resolve() | ||||
|     } | ||||
|     return this.client.client.sendNotification(method, params) | ||||
|   } | ||||
|  | ||||
|   async getCompletion(params: CopilotLspCompletionParams) { | ||||
| @ -253,6 +205,33 @@ export class LanguageServerClient { | ||||
|     return response | ||||
|   } | ||||
|  | ||||
|   getServerCapabilities(): LSP.ServerCapabilities<any> | null { | ||||
|     if (!this.client.client) { | ||||
|       return null | ||||
|     } | ||||
|  | ||||
|     // TODO: Fix this type | ||||
|     return null | ||||
|   } | ||||
|  | ||||
|   async updateSemanticTokens(uri: string) { | ||||
|     // Make sure we can only run, if we aren't already running. | ||||
|     if (!this.isUpdatingSemanticTokens) { | ||||
|       this.isUpdatingSemanticTokens = true | ||||
|  | ||||
|       this.semanticTokens = await this.request( | ||||
|         'textDocument/semanticTokens/full', | ||||
|         { | ||||
|           textDocument: { | ||||
|             uri, | ||||
|           }, | ||||
|         } | ||||
|       ) | ||||
|  | ||||
|       this.isUpdatingSemanticTokens = false | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   async accept(uuid: string) { | ||||
|     const badUids = this.queuedUids.filter((u) => u !== uuid) | ||||
|     this.queuedUids = [] | ||||
| @ -286,6 +265,7 @@ export class LanguageServerClient { | ||||
|     return await this.request('kcl/updateCanExecute', params) | ||||
|   } | ||||
|  | ||||
|   // TODO: Fix this type | ||||
|   private processNotifications(notification: LSP.NotificationMessage) { | ||||
|     for (const plugin of this.plugins) plugin.processNotification(notification) | ||||
|   } | ||||
|  | ||||
| @ -122,13 +122,13 @@ export function kclPlugin(options: LanguageServerOptions): Extension { | ||||
|           const line = state.doc.lineAt(pos) | ||||
|           let trigKind: CompletionTriggerKind = CompletionTriggerKind.Invoked | ||||
|           let trigChar: string | undefined | ||||
|           const serverCapabilities = plugin.client.getServerCapabilities() | ||||
|           if ( | ||||
|             serverCapabilities && | ||||
|             !explicit && | ||||
|             plugin.client | ||||
|               .getServerCapabilities() | ||||
|               .completionProvider?.triggerCharacters?.includes( | ||||
|                 line.text[pos - line.from - 1] | ||||
|               ) | ||||
|             serverCapabilities.completionProvider?.triggerCharacters?.includes( | ||||
|               line.text[pos - line.from - 1] | ||||
|             ) | ||||
|           ) { | ||||
|             trigKind = CompletionTriggerKind.TriggerCharacter | ||||
|             trigChar = line.text[pos - line.from - 1] | ||||
|  | ||||
| @ -1,168 +0,0 @@ | ||||
| // Extends the codemirror Parser for kcl. | ||||
|  | ||||
| import { | ||||
|   Parser, | ||||
|   Input, | ||||
|   TreeFragment, | ||||
|   PartialParse, | ||||
|   Tree, | ||||
|   NodeType, | ||||
|   NodeSet, | ||||
| } from '@lezer/common' | ||||
| import { LanguageServerClient } from 'editor/plugins/lsp' | ||||
| import { posToOffset } from 'editor/plugins/lsp/util' | ||||
| import { SemanticToken } from './semantic_tokens' | ||||
| import { DocInput } from '@codemirror/language' | ||||
| import { tags, styleTags } from '@lezer/highlight' | ||||
|  | ||||
| export default class KclParser extends Parser { | ||||
|   private client: LanguageServerClient | ||||
|  | ||||
|   constructor(client: LanguageServerClient) { | ||||
|     super() | ||||
|     this.client = client | ||||
|   } | ||||
|  | ||||
|   createParse( | ||||
|     input: Input, | ||||
|     fragments: readonly TreeFragment[], | ||||
|     ranges: readonly { from: number; to: number }[] | ||||
|   ): PartialParse { | ||||
|     let parse: PartialParse = new Context(this, input, fragments, ranges) | ||||
|     return parse | ||||
|   } | ||||
|  | ||||
|   getTokenTypes(): string[] { | ||||
|     return this.client.getServerCapabilities().semanticTokensProvider!.legend | ||||
|       .tokenTypes | ||||
|   } | ||||
|  | ||||
|   getSemanticTokens(): SemanticToken[] { | ||||
|     return this.client.getSemanticTokens() | ||||
|   } | ||||
| } | ||||
|  | ||||
| class Context implements PartialParse { | ||||
|   private parser: KclParser | ||||
|   private input: DocInput | ||||
|   private fragments: readonly TreeFragment[] | ||||
|   private ranges: readonly { from: number; to: number }[] | ||||
|  | ||||
|   private nodeTypes: { [key: string]: NodeType } | ||||
|   stoppedAt: number = 0 | ||||
|  | ||||
|   private semanticTokens: SemanticToken[] = [] | ||||
|   private currentLine: number = 0 | ||||
|   private currentColumn: number = 0 | ||||
|   private nodeSet: NodeSet | ||||
|  | ||||
|   constructor( | ||||
|     /// The parser configuration used. | ||||
|     parser: KclParser, | ||||
|     input: Input, | ||||
|     fragments: readonly TreeFragment[], | ||||
|     ranges: readonly { from: number; to: number }[] | ||||
|   ) { | ||||
|     this.parser = parser | ||||
|     this.input = input as DocInput | ||||
|     this.fragments = fragments | ||||
|     this.ranges = ranges | ||||
|  | ||||
|     // Iterate over the semantic token types and create a node type for each. | ||||
|     this.nodeTypes = {} | ||||
|     let nodeArray: NodeType[] = [] | ||||
|     this.parser.getTokenTypes().forEach((tokenType, index) => { | ||||
|       const nodeType = NodeType.define({ | ||||
|         id: index, | ||||
|         name: tokenType, | ||||
|         // props: [this.styleTags], | ||||
|       }) | ||||
|       this.nodeTypes[tokenType] = nodeType | ||||
|       nodeArray.push(nodeType) | ||||
|     }) | ||||
|  | ||||
|     this.semanticTokens = this.parser.getSemanticTokens() | ||||
|     const styles = styleTags({ | ||||
|       number: tags.number, | ||||
|       variable: tags.variableName, | ||||
|       operator: tags.operator, | ||||
|       keyword: tags.keyword, | ||||
|       string: tags.string, | ||||
|       comment: tags.comment, | ||||
|       function: tags.function(tags.variableName), | ||||
|     }) | ||||
|     this.nodeSet = new NodeSet(nodeArray).extend(styles) | ||||
|   } | ||||
|  | ||||
|   get parsedPos(): number { | ||||
|     return 0 | ||||
|   } | ||||
|  | ||||
|   advance(): Tree | null { | ||||
|     if (this.semanticTokens.length === 0) { | ||||
|       return new Tree(NodeType.none, [], [], 0) | ||||
|     } | ||||
|     const tree = this.createTree(this.semanticTokens[0], 0) | ||||
|     this.stoppedAt = this.input.doc.length | ||||
|     return tree | ||||
|   } | ||||
|  | ||||
|   createTree(token: SemanticToken, index: number): Tree { | ||||
|     const changedLine = token.delta_line !== 0 | ||||
|     this.currentLine += token.delta_line | ||||
|     if (changedLine) { | ||||
|       this.currentColumn = 0 | ||||
|     } | ||||
|     this.currentColumn += token.delta_start | ||||
|  | ||||
|     // Let's get our position relative to the start of the file. | ||||
|     let currentPosition = posToOffset(this.input.doc, { | ||||
|       line: this.currentLine, | ||||
|       character: this.currentColumn, | ||||
|     }) | ||||
|  | ||||
|     const nodeType = this.nodeSet.types[this.nodeTypes[token.token_type].id] | ||||
|  | ||||
|     if (currentPosition === undefined) { | ||||
|       // This is bad and weird. | ||||
|       return new Tree(nodeType, [], [], token.length) | ||||
|     } | ||||
|  | ||||
|     if (index >= this.semanticTokens.length - 1) { | ||||
|       // We have no children. | ||||
|       return new Tree(nodeType, [], [], token.length) | ||||
|     } | ||||
|  | ||||
|     const nextIndex = index + 1 | ||||
|     const nextToken = this.semanticTokens[nextIndex] | ||||
|     const changedLineNext = nextToken.delta_line !== 0 | ||||
|     const nextLine = this.currentLine + nextToken.delta_line | ||||
|     const nextColumn = changedLineNext | ||||
|       ? nextToken.delta_start | ||||
|       : this.currentColumn + nextToken.delta_start | ||||
|     const nextPosition = posToOffset(this.input.doc, { | ||||
|       line: nextLine, | ||||
|       character: nextColumn, | ||||
|     }) | ||||
|  | ||||
|     if (nextPosition === undefined) { | ||||
|       // This is bad and weird. | ||||
|       return new Tree(nodeType, [], [], token.length) | ||||
|     } | ||||
|  | ||||
|     // Let's get the | ||||
|  | ||||
|     return new Tree( | ||||
|       nodeType, | ||||
|       [this.createTree(nextToken, nextIndex)], | ||||
|  | ||||
|       // The positions (offsets relative to the start of this tree) of the children. | ||||
|       [nextPosition - currentPosition], | ||||
|       token.length | ||||
|     ) | ||||
|   } | ||||
|  | ||||
|   stopAt(pos: number) { | ||||
|     this.stoppedAt = pos | ||||
|   } | ||||
| } | ||||
| @ -1,51 +0,0 @@ | ||||
| import type * as LSP from 'vscode-languageserver-protocol' | ||||
|  | ||||
| export class SemanticToken { | ||||
|   delta_line: number | ||||
|   delta_start: number | ||||
|   length: number | ||||
|   token_type: string | ||||
|   token_modifiers_bitset: string | ||||
|  | ||||
|   constructor( | ||||
|     delta_line = 0, | ||||
|     delta_start = 0, | ||||
|     length = 0, | ||||
|     token_type = '', | ||||
|     token_modifiers_bitset = '' | ||||
|   ) { | ||||
|     this.delta_line = delta_line | ||||
|     this.delta_start = delta_start | ||||
|     this.length = length | ||||
|     this.token_type = token_type | ||||
|     this.token_modifiers_bitset = token_modifiers_bitset | ||||
|   } | ||||
| } | ||||
|  | ||||
| export async function deserializeTokens( | ||||
|   data: number[], | ||||
|   semanticTokensProvider?: LSP.SemanticTokensOptions | ||||
| ): Promise<SemanticToken[]> { | ||||
|   if (!semanticTokensProvider) { | ||||
|     return [] | ||||
|   } | ||||
|   // Check if data length is divisible by 5 | ||||
|   if (data.length % 5 !== 0) { | ||||
|     return Promise.reject(new Error('Length is not divisible by 5')) | ||||
|   } | ||||
|  | ||||
|   const tokens = [] | ||||
|   for (let i = 0; i < data.length; i += 5) { | ||||
|     tokens.push( | ||||
|       new SemanticToken( | ||||
|         data[i], | ||||
|         data[i + 1], | ||||
|         data[i + 2], | ||||
|         semanticTokensProvider.legend.tokenTypes[data[i + 3]], | ||||
|         semanticTokensProvider.legend.tokenModifiers[data[i + 4]] | ||||
|       ) | ||||
|     ) | ||||
|   } | ||||
|  | ||||
|   return tokens | ||||
| } | ||||
| @ -145,11 +145,7 @@ export class LanguageServerPlugin implements PluginValue { | ||||
|     view: EditorView, | ||||
|     { line, character }: { line: number; character: number } | ||||
|   ): Promise<Tooltip | null> { | ||||
|     if ( | ||||
|       !this.client.ready || | ||||
|       !this.client.getServerCapabilities().hoverProvider | ||||
|     ) | ||||
|       return null | ||||
|     if (!this.client.ready) return null | ||||
|  | ||||
|     this.sendChange({ documentText: view.state.doc.toString() }) | ||||
|     const result = await this.client.textDocumentHover({ | ||||
| @ -175,11 +171,7 @@ export class LanguageServerPlugin implements PluginValue { | ||||
|   } | ||||
|  | ||||
|   async getFoldingRanges(): Promise<LSP.FoldingRange[] | null> { | ||||
|     if ( | ||||
|       !this.client.ready || | ||||
|       !this.client.getServerCapabilities().foldingRangeProvider | ||||
|     ) | ||||
|       return null | ||||
|     if (!this.client.ready) return null | ||||
|     const result = await this.client.textDocumentFoldingRange({ | ||||
|       textDocument: { uri: this.documentUri }, | ||||
|     }) | ||||
| @ -259,11 +251,7 @@ export class LanguageServerPlugin implements PluginValue { | ||||
|   } | ||||
|  | ||||
|   async requestFormatting() { | ||||
|     if ( | ||||
|       !this.client.ready || | ||||
|       !this.client.getServerCapabilities().documentFormattingProvider | ||||
|     ) | ||||
|       return null | ||||
|     if (!this.client.ready) return null | ||||
|  | ||||
|     this.client.textDocumentDidChange({ | ||||
|       textDocument: { | ||||
| @ -309,11 +297,7 @@ export class LanguageServerPlugin implements PluginValue { | ||||
|       triggerCharacter: string | undefined | ||||
|     } | ||||
|   ): Promise<CompletionResult | null> { | ||||
|     if ( | ||||
|       !this.client.ready || | ||||
|       !this.client.getServerCapabilities().completionProvider | ||||
|     ) | ||||
|       return null | ||||
|     if (!this.client.ready) return null | ||||
|  | ||||
|     this.sendChange({ | ||||
|       documentText: context.state.doc.toString(), | ||||
|  | ||||
| @ -33,15 +33,19 @@ export default class Queue<T> | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   constructor() { | ||||
|   constructor(stream?: WritableStream<T>) { | ||||
|     const closed = this.#closed | ||||
|     const promises = this.#promises | ||||
|     const resolvers = this.#resolvers | ||||
|     this.#stream = new WritableStream({ | ||||
|       write(item: T): void { | ||||
|         Queue.#__enqueue(closed, promises, resolvers, item) | ||||
|       }, | ||||
|     }) | ||||
|     if (stream) { | ||||
|       this.#stream = stream | ||||
|     } else { | ||||
|       this.#stream = new WritableStream({ | ||||
|         write(item: T): void { | ||||
|           Queue.#__enqueue(closed, promises, resolvers, item) | ||||
|         }, | ||||
|       }) | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   #add(): void { | ||||
| @ -1,82 +0,0 @@ | ||||
| import { | ||||
|   Registration, | ||||
|   ServerCapabilities, | ||||
|   Unregistration, | ||||
| } from 'vscode-languageserver-protocol' | ||||
|  | ||||
| interface IFlexibleServerCapabilities extends ServerCapabilities { | ||||
|   [key: string]: any | ||||
| } | ||||
|  | ||||
| interface IMethodServerCapabilityProviderDictionary { | ||||
|   [key: string]: string | ||||
| } | ||||
|  | ||||
| const ServerCapabilitiesProviders: IMethodServerCapabilityProviderDictionary = { | ||||
|   'textDocument/hover': 'hoverProvider', | ||||
|   'textDocument/completion': 'completionProvider', | ||||
|   'textDocument/signatureHelp': 'signatureHelpProvider', | ||||
|   'textDocument/definition': 'definitionProvider', | ||||
|   'textDocument/typeDefinition': 'typeDefinitionProvider', | ||||
|   'textDocument/implementation': 'implementationProvider', | ||||
|   'textDocument/references': 'referencesProvider', | ||||
|   'textDocument/documentHighlight': 'documentHighlightProvider', | ||||
|   'textDocument/documentSymbol': 'documentSymbolProvider', | ||||
|   'textDocument/workspaceSymbol': 'workspaceSymbolProvider', | ||||
|   'textDocument/codeAction': 'codeActionProvider', | ||||
|   'textDocument/codeLens': 'codeLensProvider', | ||||
|   'textDocument/documentFormatting': 'documentFormattingProvider', | ||||
|   'textDocument/documentRangeFormatting': 'documentRangeFormattingProvider', | ||||
|   'textDocument/documentOnTypeFormatting': 'documentOnTypeFormattingProvider', | ||||
|   'textDocument/rename': 'renameProvider', | ||||
|   'textDocument/documentLink': 'documentLinkProvider', | ||||
|   'textDocument/color': 'colorProvider', | ||||
|   'textDocument/foldingRange': 'foldingRangeProvider', | ||||
|   'textDocument/declaration': 'declarationProvider', | ||||
|   'textDocument/executeCommand': 'executeCommandProvider', | ||||
|   'textDocument/semanticTokens/full': 'semanticTokensProvider', | ||||
|   'textDocument/publishDiagnostics': 'diagnosticsProvider', | ||||
| } | ||||
|  | ||||
| function registerServerCapability( | ||||
|   serverCapabilities: ServerCapabilities, | ||||
|   registration: Registration | ||||
| ): ServerCapabilities | Error { | ||||
|   const serverCapabilitiesCopy = JSON.parse( | ||||
|     JSON.stringify(serverCapabilities) | ||||
|   ) as IFlexibleServerCapabilities | ||||
|   const { method, registerOptions } = registration | ||||
|   const providerName = ServerCapabilitiesProviders[method] | ||||
|  | ||||
|   if (providerName) { | ||||
|     if (!registerOptions) { | ||||
|       serverCapabilitiesCopy[providerName] = true | ||||
|     } else { | ||||
|       serverCapabilitiesCopy[providerName] = Object.assign( | ||||
|         {}, | ||||
|         JSON.parse(JSON.stringify(registerOptions)) | ||||
|       ) | ||||
|     } | ||||
|   } else { | ||||
|     return new Error('Could not register server capability.') | ||||
|   } | ||||
|  | ||||
|   return serverCapabilitiesCopy | ||||
| } | ||||
|  | ||||
| function unregisterServerCapability( | ||||
|   serverCapabilities: ServerCapabilities, | ||||
|   unregistration: Unregistration | ||||
| ): ServerCapabilities { | ||||
|   const serverCapabilitiesCopy = JSON.parse( | ||||
|     JSON.stringify(serverCapabilities) | ||||
|   ) as IFlexibleServerCapabilities | ||||
|   const { method } = unregistration | ||||
|   const providerName = ServerCapabilitiesProviders[method] | ||||
|  | ||||
|   delete serverCapabilitiesCopy[providerName] | ||||
|  | ||||
|   return serverCapabilitiesCopy | ||||
| } | ||||
|  | ||||
| export { registerServerCapability, unregisterServerCapability } | ||||
| @ -1,21 +0,0 @@ | ||||
| import { Message } from 'vscode-languageserver-protocol' | ||||
|  | ||||
| const env = import.meta.env.MODE | ||||
|  | ||||
| export default class Tracer { | ||||
|   static client(message: string): void { | ||||
|     // These are really noisy, so we have a special env var for them. | ||||
|     if (env === 'lsp_tracing') { | ||||
|       console.log('lsp client message', message) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   static server(input: string | Message): void { | ||||
|     // These are really noisy, so we have a special env var for them. | ||||
|     if (env === 'lsp_tracing') { | ||||
|       const message: string = | ||||
|         typeof input === 'string' ? input : JSON.stringify(input) | ||||
|       console.log('lsp server message', message) | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -4,22 +4,27 @@ export enum LspWorker { | ||||
|   Kcl = 'kcl', | ||||
|   Copilot = 'copilot', | ||||
| } | ||||
| export interface KclWorkerOptions { | ||||
|   wasmUrl: string | ||||
|  | ||||
| interface LspWorkerOptions { | ||||
|   token: string | ||||
|   baseUnit: UnitLength | ||||
|   apiBaseUrl: string | ||||
|   callback: () => void | ||||
|   wasmUrl: string | ||||
| } | ||||
|  | ||||
| export interface CopilotWorkerOptions { | ||||
|   wasmUrl: string | ||||
|   token: string | ||||
|   apiBaseUrl: string | ||||
| export interface KclWorkerOptions extends LspWorkerOptions { | ||||
|   baseUnit: UnitLength | ||||
| } | ||||
|  | ||||
| export interface CopilotWorkerOptions extends LspWorkerOptions {} | ||||
|  | ||||
| export interface LspContext { | ||||
|   worker: LspWorker | ||||
|   options: KclWorkerOptions | CopilotWorkerOptions | ||||
| } | ||||
|  | ||||
| export enum LspWorkerEventType { | ||||
|   Init = 'init', | ||||
|   Call = 'call', | ||||
| } | ||||
|  | ||||
| export interface LspWorkerEvent { | ||||
|  | ||||
| @ -1,23 +1,77 @@ | ||||
| import { Codec, FromServer, IntoServer } from 'editor/plugins/lsp/codec' | ||||
| import { fileSystemManager } from 'lang/std/fileSystemManager' | ||||
| import init, { | ||||
|   ServerConfig, | ||||
|   copilot_lsp_run, | ||||
|   kcl_lsp_run, | ||||
| } from 'wasm-lib/pkg/wasm_lib' | ||||
| import * as jsrpc from 'json-rpc-2.0' | ||||
| import { | ||||
|   LspWorkerEventType, | ||||
|   LspWorkerEvent, | ||||
|   LspWorker, | ||||
|   KclWorkerOptions, | ||||
|   CopilotWorkerOptions, | ||||
| } from 'editor/plugins/lsp/types' | ||||
| import { EngineCommandManager } from 'lang/std/engineConnection' | ||||
| import { err } from 'lib/trap' | ||||
| import { Message } from 'vscode-languageserver' | ||||
| import { LspWorkerEvent, LspWorkerEventType } from 'editor/plugins/lsp/types' | ||||
| import Queue from 'editor/plugins/lsp/queue' | ||||
| import { | ||||
|   BrowserMessageReader, | ||||
|   BrowserMessageWriter, | ||||
| } from 'vscode-languageserver-protocol/browser' | ||||
|  | ||||
| const intoServer: IntoServer = new IntoServer() | ||||
| const fromServer: FromServer | Error = FromServer.create() | ||||
| class Headers { | ||||
|   static add(message: string): string { | ||||
|     return `Content-Length: ${message.length}\r\n\r\n${message}` | ||||
|   } | ||||
|  | ||||
|   static remove(delimited: string): string { | ||||
|     return delimited.replace(/^Content-Length:\s*\d+\s*/, '') | ||||
|   } | ||||
| } | ||||
|  | ||||
| export const encoder = new TextEncoder() | ||||
| export const decoder = new TextDecoder() | ||||
|  | ||||
| class Codec { | ||||
|   static encode(message: Message): Uint8Array { | ||||
|     const rpc = JSON.stringify(message.jsonrpc) | ||||
|     const delimited = Headers.add(rpc) | ||||
|     return encoder.encode(delimited) | ||||
|   } | ||||
|  | ||||
|   static decode<T>(data: Uint8Array): T { | ||||
|     const delimited = decoder.decode(data) | ||||
|     const message = Headers.remove(delimited) | ||||
|     return JSON.parse(message) as T | ||||
|   } | ||||
| } | ||||
|  | ||||
| class IntoServer extends Queue<Uint8Array> { | ||||
|   constructor(reader: BrowserMessageReader) { | ||||
|     super() | ||||
|     reader.listen((message: Message) => { | ||||
|       super.enqueue(Codec.encode(message)) | ||||
|     }) | ||||
|   } | ||||
| } | ||||
|  | ||||
| class FromServer extends Queue<Uint8Array> { | ||||
|   constructor(writer: BrowserMessageWriter) { | ||||
|     super( | ||||
|       new WritableStream({ | ||||
|         write(item: Uint8Array): void { | ||||
|           writer.write(Codec.decode(item)) | ||||
|         }, | ||||
|       }) | ||||
|     ) | ||||
|   } | ||||
| } | ||||
|  | ||||
| const browserReader = new BrowserMessageReader(self) | ||||
| const browserWriter = new BrowserMessageWriter(self) | ||||
|  | ||||
| const intoServer = new IntoServer(browserReader) | ||||
| const fromServer = new FromServer(browserWriter) | ||||
|  | ||||
| // Initialise the wasm module. | ||||
| const initialise = async (wasmUrl: string) => { | ||||
| @ -57,7 +111,7 @@ export async function kclLspRun( | ||||
| } | ||||
|  | ||||
| onmessage = function (event) { | ||||
|   if (err(fromServer)) return | ||||
|   if (err(intoServer)) return | ||||
|   const { worker, eventType, eventData }: LspWorkerEvent = event.data | ||||
|  | ||||
|   switch (eventType) { | ||||
| @ -95,35 +149,7 @@ onmessage = function (event) { | ||||
|           console.error('Worker: Error loading wasm module', worker, error) | ||||
|         }) | ||||
|       break | ||||
|     case LspWorkerEventType.Call: | ||||
|       const data = eventData as Uint8Array | ||||
|       intoServer.enqueue(data) | ||||
|       const json: jsrpc.JSONRPCRequest = Codec.decode(data) | ||||
|       if (null != json.id) { | ||||
|         // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||||
|         fromServer.responses.get(json.id)!.then((response) => { | ||||
|           const encoded = Codec.encode(response as jsrpc.JSONRPCResponse) | ||||
|           postMessage(encoded) | ||||
|         }) | ||||
|       } | ||||
|       break | ||||
|     default: | ||||
|       console.error('Worker: Unknown message type', worker, eventType) | ||||
|   } | ||||
| } | ||||
|  | ||||
| new Promise<void>(async (resolve) => { | ||||
|   if (err(fromServer)) return | ||||
|   for await (const requests of fromServer.requests) { | ||||
|     const encoded = Codec.encode(requests as jsrpc.JSONRPCRequest) | ||||
|     postMessage(encoded) | ||||
|   } | ||||
| }) | ||||
|  | ||||
| new Promise<void>(async (resolve) => { | ||||
|   if (err(fromServer)) return | ||||
|   for await (const notification of fromServer.notifications) { | ||||
|     const encoded = Codec.encode(notification as jsrpc.JSONRPCRequest) | ||||
|     postMessage(encoded) | ||||
|   } | ||||
| }) | ||||
|  | ||||
| @ -19,7 +19,6 @@ import { | ||||
|   createPipeSubstitution, | ||||
| } from './modifyAst' | ||||
| import { err } from 'lib/trap' | ||||
| import { warn } from 'node:console' | ||||
|  | ||||
| beforeAll(async () => { | ||||
|   await initPromise | ||||
|  | ||||
| @ -24,11 +24,7 @@ import { | ||||
|   isNotLiteralArrayOrStatic, | ||||
| } from 'lang/std/sketchcombos' | ||||
| import { toolTips, ToolTip } from '../../useStore' | ||||
| import { | ||||
|   createIdentifier, | ||||
|   createPipeExpression, | ||||
|   splitPathAtPipeExpression, | ||||
| } from '../modifyAst' | ||||
| import { createPipeExpression, splitPathAtPipeExpression } from '../modifyAst' | ||||
|  | ||||
| import { | ||||
|   SketchLineHelper, | ||||
|  | ||||
							
								
								
									
										285
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										285
									
								
								yarn.lock
									
									
									
									
									
								
							| @ -1631,16 +1631,6 @@ | ||||
|     "@nodelib/fs.scandir" "2.1.5" | ||||
|     fastq "^1.6.0" | ||||
|  | ||||
| "@open-rpc/client-js@^1.8.1": | ||||
|   version "1.8.1" | ||||
|   resolved "https://registry.yarnpkg.com/@open-rpc/client-js/-/client-js-1.8.1.tgz#73b5a5bf237f24b14c3c89205b1fca3aea213213" | ||||
|   integrity sha512-vV+Hetl688nY/oWI9IFY0iKDrWuLdYhf7OIKI6U1DcnJV7r4gAgwRJjEr1QVYszUc0gjkHoQJzqevmXMGLyA0g== | ||||
|   dependencies: | ||||
|     isomorphic-fetch "^3.0.0" | ||||
|     isomorphic-ws "^5.0.0" | ||||
|     strict-event-emitter-types "^2.0.0" | ||||
|     ws "^7.0.0" | ||||
|  | ||||
| "@pkgjs/parseargs@^0.11.0": | ||||
|   version "0.11.0" | ||||
|   resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" | ||||
| @ -2026,6 +2016,11 @@ | ||||
|   resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-14.5.2.tgz#db7257d727c891905947bd1c1a99da20e03c2ebd" | ||||
|   integrity sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ== | ||||
|  | ||||
| "@tootallnate/once@1": | ||||
|   version "1.1.2" | ||||
|   resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" | ||||
|   integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== | ||||
|  | ||||
| "@tootallnate/quickjs-emscripten@^0.23.0": | ||||
|   version "0.23.0" | ||||
|   resolved "https://registry.yarnpkg.com/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz#db4ecfd499a9765ab24002c3b696d02e6d32a12c" | ||||
| @ -2759,6 +2754,20 @@ acorn@^8.11.0, acorn@^8.11.3, acorn@^8.4.1, acorn@^8.9.0: | ||||
|   resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.0.tgz#1627bfa2e058148036133b8d9b51a700663c294c" | ||||
|   integrity sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw== | ||||
|  | ||||
| agent-base@4, agent-base@^4.3.0: | ||||
|   version "4.3.0" | ||||
|   resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" | ||||
|   integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== | ||||
|   dependencies: | ||||
|     es6-promisify "^5.0.0" | ||||
|  | ||||
| agent-base@6: | ||||
|   version "6.0.2" | ||||
|   resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" | ||||
|   integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== | ||||
|   dependencies: | ||||
|     debug "4" | ||||
|  | ||||
| agent-base@^7.0.2, agent-base@^7.1.0, agent-base@^7.1.1: | ||||
|   version "7.1.1" | ||||
|   resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.1.tgz#bdbded7dfb096b751a2a087eeeb9664725b2e317" | ||||
| @ -3285,6 +3294,11 @@ buffer-crc32@~0.2.3: | ||||
|   resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" | ||||
|   integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== | ||||
|  | ||||
| buffer-from@^1.0.0: | ||||
|   version "1.1.2" | ||||
|   resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" | ||||
|   integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== | ||||
|  | ||||
| buffer@^5.2.1, buffer@^5.5.0: | ||||
|   version "5.7.1" | ||||
|   resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" | ||||
| @ -3551,6 +3565,11 @@ combined-stream@^1.0.8: | ||||
|   dependencies: | ||||
|     delayed-stream "~1.0.0" | ||||
|  | ||||
| commander@2.15.1: | ||||
|   version "2.15.1" | ||||
|   resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" | ||||
|   integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== | ||||
|  | ||||
| commander@^4.0.0: | ||||
|   version "4.1.1" | ||||
|   resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" | ||||
| @ -3760,6 +3779,13 @@ debounce-promise@^3.1.2: | ||||
|   resolved "https://registry.yarnpkg.com/debounce-promise/-/debounce-promise-3.1.2.tgz#320fb8c7d15a344455cd33cee5ab63530b6dc7c5" | ||||
|   integrity sha512-rZHcgBkbYavBeD9ej6sP56XfG53d51CD4dnaw989YX/nZ/ZJfgRx/9ePKmTNiUiyQvh4mtrMoS3OAWW+yoYtpg== | ||||
|  | ||||
| debug@3.1.0: | ||||
|   version "3.1.0" | ||||
|   resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" | ||||
|   integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== | ||||
|   dependencies: | ||||
|     ms "2.0.0" | ||||
|  | ||||
| debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: | ||||
|   version "4.3.5" | ||||
|   resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.5.tgz#e83444eceb9fedd4a1da56d671ae2446a01a6e1e" | ||||
| @ -3774,7 +3800,7 @@ debug@4.3.4: | ||||
|   dependencies: | ||||
|     ms "2.1.2" | ||||
|  | ||||
| debug@^3.2.7: | ||||
| debug@^3.1.0, debug@^3.2.7: | ||||
|   version "3.2.7" | ||||
|   resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" | ||||
|   integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== | ||||
| @ -3889,6 +3915,11 @@ diff-sequences@^29.6.3: | ||||
|   resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" | ||||
|   integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== | ||||
|  | ||||
| diff@3.5.0: | ||||
|   version "3.5.0" | ||||
|   resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" | ||||
|   integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== | ||||
|  | ||||
| diff@5.0.0: | ||||
|   version "5.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" | ||||
| @ -4131,6 +4162,18 @@ es-to-primitive@^1.2.1: | ||||
|     is-date-object "^1.0.1" | ||||
|     is-symbol "^1.0.2" | ||||
|  | ||||
| es6-promise@^4.0.3: | ||||
|   version "4.2.8" | ||||
|   resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" | ||||
|   integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== | ||||
|  | ||||
| es6-promisify@^5.0.0: | ||||
|   version "5.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" | ||||
|   integrity sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ== | ||||
|   dependencies: | ||||
|     es6-promise "^4.0.3" | ||||
|  | ||||
| esbuild@^0.21.3: | ||||
|   version "0.21.5" | ||||
|   resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d" | ||||
| @ -4165,16 +4208,16 @@ escalade@^3.1.1, escalade@^3.1.2: | ||||
|   resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" | ||||
|   integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== | ||||
|  | ||||
| escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5: | ||||
|   version "1.0.5" | ||||
|   resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" | ||||
|   integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== | ||||
|  | ||||
| escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: | ||||
|   version "4.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" | ||||
|   integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== | ||||
|  | ||||
| escape-string-regexp@^1.0.5: | ||||
|   version "1.0.5" | ||||
|   resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" | ||||
|   integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== | ||||
|  | ||||
| escape-string-regexp@^2.0.0: | ||||
|   version "2.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" | ||||
| @ -4929,6 +4972,18 @@ glob-parent@^6.0.2: | ||||
|   dependencies: | ||||
|     is-glob "^4.0.3" | ||||
|  | ||||
| glob@7.1.2: | ||||
|   version "7.1.2" | ||||
|   resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" | ||||
|   integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== | ||||
|   dependencies: | ||||
|     fs.realpath "^1.0.0" | ||||
|     inflight "^1.0.4" | ||||
|     inherits "2" | ||||
|     minimatch "^3.0.4" | ||||
|     once "^1.3.0" | ||||
|     path-is-absolute "^1.0.0" | ||||
|  | ||||
| glob@8.1.0: | ||||
|   version "8.1.0" | ||||
|   resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" | ||||
| @ -4951,7 +5006,7 @@ glob@^10.0.0, glob@^10.2.2, glob@^10.3.10: | ||||
|     minipass "^7.1.2" | ||||
|     path-scurry "^1.11.1" | ||||
|  | ||||
| glob@^7.1.3: | ||||
| glob@^7.1.2, glob@^7.1.3: | ||||
|   version "7.2.3" | ||||
|   resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" | ||||
|   integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== | ||||
| @ -5072,6 +5127,11 @@ graphemer@^1.4.0: | ||||
|   resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" | ||||
|   integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== | ||||
|  | ||||
| growl@1.10.5: | ||||
|   version "1.10.5" | ||||
|   resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" | ||||
|   integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== | ||||
|  | ||||
| happy-dom@^14.3.10: | ||||
|   version "14.12.0" | ||||
|   resolved "https://registry.yarnpkg.com/happy-dom/-/happy-dom-14.12.0.tgz#40c748578c6ebfb707e6ae69179d6c541d8f63b3" | ||||
| @ -5127,6 +5187,11 @@ hasown@^2.0.0, hasown@^2.0.1, hasown@^2.0.2: | ||||
|   dependencies: | ||||
|     function-bind "^1.1.2" | ||||
|  | ||||
| he@1.1.1: | ||||
|   version "1.1.1" | ||||
|   resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" | ||||
|   integrity sha512-z/GDPjlRMNOa2XJiB4em8wJpuuBfrFOlYKTZxtpkdr1uPdibHI8rYA3MY0KDObpVyaes0e/aunid/t88ZI2EKA== | ||||
|  | ||||
| he@1.2.0, he@^1.2.0: | ||||
|   version "1.2.0" | ||||
|   resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" | ||||
| @ -5166,6 +5231,23 @@ http-cache-semantics@^4.1.1: | ||||
|   resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" | ||||
|   integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== | ||||
|  | ||||
| http-proxy-agent@^2.1.0: | ||||
|   version "2.1.0" | ||||
|   resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" | ||||
|   integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg== | ||||
|   dependencies: | ||||
|     agent-base "4" | ||||
|     debug "3.1.0" | ||||
|  | ||||
| http-proxy-agent@^4.0.1: | ||||
|   version "4.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" | ||||
|   integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== | ||||
|   dependencies: | ||||
|     "@tootallnate/once" "1" | ||||
|     agent-base "6" | ||||
|     debug "4" | ||||
|  | ||||
| http-proxy-agent@^7.0.0, http-proxy-agent@^7.0.2: | ||||
|   version "7.0.2" | ||||
|   resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz#9a8b1f246866c028509486585f62b8f2c18c270e" | ||||
| @ -5210,6 +5292,22 @@ http2-wrapper@^2.1.10: | ||||
|     quick-lru "^5.1.1" | ||||
|     resolve-alpn "^1.2.0" | ||||
|  | ||||
| https-proxy-agent@^2.2.1: | ||||
|   version "2.2.4" | ||||
|   resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b" | ||||
|   integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg== | ||||
|   dependencies: | ||||
|     agent-base "^4.3.0" | ||||
|     debug "^3.1.0" | ||||
|  | ||||
| https-proxy-agent@^5.0.0: | ||||
|   version "5.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" | ||||
|   integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== | ||||
|   dependencies: | ||||
|     agent-base "6" | ||||
|     debug "4" | ||||
|  | ||||
| https-proxy-agent@^7.0.0, https-proxy-agent@^7.0.2, https-proxy-agent@^7.0.4: | ||||
|   version "7.0.4" | ||||
|   resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz#8e97b841a029ad8ddc8731f26595bad868cb4168" | ||||
| @ -5581,11 +5679,6 @@ isomorphic-fetch@^3.0.0: | ||||
|     node-fetch "^2.6.1" | ||||
|     whatwg-fetch "^3.4.1" | ||||
|  | ||||
| isomorphic-ws@^5.0.0: | ||||
|   version "5.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf" | ||||
|   integrity sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw== | ||||
|  | ||||
| iterator.prototype@^1.1.2: | ||||
|   version "1.1.2" | ||||
|   resolved "https://registry.yarnpkg.com/iterator.prototype/-/iterator.prototype-1.1.2.tgz#5e29c8924f01916cb9335f1ff80619dcff22b0c0" | ||||
| @ -5731,7 +5824,7 @@ json-parse-even-better-errors@^3.0.0: | ||||
|   resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz#b43d35e89c0f3be6b5fbbe9dc6c82467b30c28da" | ||||
|   integrity sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ== | ||||
|  | ||||
| json-rpc-2.0@^1.6.0: | ||||
| json-rpc-2.0@^1.7.0: | ||||
|   version "1.7.0" | ||||
|   resolved "https://registry.yarnpkg.com/json-rpc-2.0/-/json-rpc-2.0-1.7.0.tgz#840deb0bc168463e12bceb462f7fe225e793fc17" | ||||
|   integrity sha512-asnLgC1qD5ytP+fvBP8uL0rvj+l8P6iYICbzZ8dVxCpESffVjzA7KkYkbKCIbavs7cllwH1ZUaNtJwphdeRqpg== | ||||
| @ -6080,6 +6173,13 @@ min-indent@^1.0.0: | ||||
|   resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" | ||||
|   integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== | ||||
|  | ||||
| minimatch@3.0.4: | ||||
|   version "3.0.4" | ||||
|   resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" | ||||
|   integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== | ||||
|   dependencies: | ||||
|     brace-expansion "^1.1.7" | ||||
|  | ||||
| minimatch@5.0.1: | ||||
|   version "5.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" | ||||
| @ -6115,6 +6215,11 @@ minimatch@~3.0.2: | ||||
|   dependencies: | ||||
|     brace-expansion "^1.1.7" | ||||
|  | ||||
| minimist@0.0.8: | ||||
|   version "0.0.8" | ||||
|   resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" | ||||
|   integrity sha512-miQKw5Hv4NS1Psg2517mV4e4dYNaO3++hjAvLOAzKqZ61rH8NS1SK+vbfBWZ5PY/Me/bEWhUwqMghEW5Fb9T7Q== | ||||
|  | ||||
| minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6, minimist@^1.2.8: | ||||
|   version "1.2.8" | ||||
|   resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" | ||||
| @ -6155,6 +6260,13 @@ mkdirp-classic@^0.5.2: | ||||
|   resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" | ||||
|   integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== | ||||
|  | ||||
| mkdirp@0.5.1: | ||||
|   version "0.5.1" | ||||
|   resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" | ||||
|   integrity sha512-SknJC52obPfGQPnjIkXbmA6+5H15E+fR+E4iR2oQ3zzCLbd7/ONua69R/Gw7AgkTLsRG+r5fzksYwWe1AgTyWA== | ||||
|   dependencies: | ||||
|     minimist "0.0.8" | ||||
|  | ||||
| mkdirp@^0.5.6: | ||||
|   version "0.5.6" | ||||
|   resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" | ||||
| @ -6203,11 +6315,33 @@ mocha@^10.0.0: | ||||
|     yargs-parser "20.2.4" | ||||
|     yargs-unparser "2.0.0" | ||||
|  | ||||
| mocha@^5.2.0: | ||||
|   version "5.2.0" | ||||
|   resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" | ||||
|   integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ== | ||||
|   dependencies: | ||||
|     browser-stdout "1.3.1" | ||||
|     commander "2.15.1" | ||||
|     debug "3.1.0" | ||||
|     diff "3.5.0" | ||||
|     escape-string-regexp "1.0.5" | ||||
|     glob "7.1.2" | ||||
|     growl "1.10.5" | ||||
|     he "1.1.1" | ||||
|     minimatch "3.0.4" | ||||
|     mkdirp "0.5.1" | ||||
|     supports-color "5.4.0" | ||||
|  | ||||
| moment@2.30.1: | ||||
|   version "2.30.1" | ||||
|   resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae" | ||||
|   integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how== | ||||
|  | ||||
| ms@2.0.0: | ||||
|   version "2.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" | ||||
|   integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== | ||||
|  | ||||
| ms@2.1.2: | ||||
|   version "2.1.2" | ||||
|   resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" | ||||
| @ -7379,6 +7513,11 @@ secure-compare@3.0.1: | ||||
|   resolved "https://registry.yarnpkg.com/secure-compare/-/secure-compare-3.0.1.tgz#f1a0329b308b221fae37b9974f3d578d0ca999e3" | ||||
|   integrity sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw== | ||||
|  | ||||
| semver@^5.4.1: | ||||
|   version "5.7.2" | ||||
|   resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" | ||||
|   integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== | ||||
|  | ||||
| semver@^6.3.1: | ||||
|   version "6.3.1" | ||||
|   resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" | ||||
| @ -7504,7 +7643,15 @@ source-map-js@^1.2.0: | ||||
|   resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af" | ||||
|   integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== | ||||
|  | ||||
| source-map@~0.6.1: | ||||
| source-map-support@^0.5.0: | ||||
|   version "0.5.21" | ||||
|   resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" | ||||
|   integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== | ||||
|   dependencies: | ||||
|     buffer-from "^1.0.0" | ||||
|     source-map "^0.6.0" | ||||
|  | ||||
| source-map@^0.6.0, source-map@~0.6.1: | ||||
|   version "0.6.1" | ||||
|   resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" | ||||
|   integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== | ||||
| @ -7583,17 +7730,21 @@ streamx@^2.15.0, streamx@^2.18.0: | ||||
|   optionalDependencies: | ||||
|     bare-events "^2.2.0" | ||||
|  | ||||
| strict-event-emitter-types@^2.0.0: | ||||
|   version "2.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/strict-event-emitter-types/-/strict-event-emitter-types-2.0.0.tgz#05e15549cb4da1694478a53543e4e2f4abcf277f" | ||||
|   integrity sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA== | ||||
|  | ||||
| string-natural-compare@^3.0.1: | ||||
|   version "3.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4" | ||||
|   integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw== | ||||
|  | ||||
| "string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: | ||||
| "string-width-cjs@npm:string-width@^4.2.0": | ||||
|   version "4.2.3" | ||||
|   resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" | ||||
|   integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== | ||||
|   dependencies: | ||||
|     emoji-regex "^8.0.0" | ||||
|     is-fullwidth-code-point "^3.0.0" | ||||
|     strip-ansi "^6.0.1" | ||||
|  | ||||
| string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: | ||||
|   version "4.2.3" | ||||
|   resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" | ||||
|   integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== | ||||
| @ -7671,7 +7822,14 @@ string_decoder@~1.1.1: | ||||
|   dependencies: | ||||
|     safe-buffer "~5.1.0" | ||||
|  | ||||
| "strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: | ||||
| "strip-ansi-cjs@npm:strip-ansi@^6.0.1": | ||||
|   version "6.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" | ||||
|   integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== | ||||
|   dependencies: | ||||
|     ansi-regex "^5.0.1" | ||||
|  | ||||
| strip-ansi@^6.0.0, strip-ansi@^6.0.1: | ||||
|   version "6.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" | ||||
|   integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== | ||||
| @ -7732,6 +7890,13 @@ sucrase@^3.32.0: | ||||
|     pirates "^4.0.1" | ||||
|     ts-interface-checker "^0.1.9" | ||||
|  | ||||
| supports-color@5.4.0: | ||||
|   version "5.4.0" | ||||
|   resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" | ||||
|   integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w== | ||||
|   dependencies: | ||||
|     has-flag "^3.0.0" | ||||
|  | ||||
| supports-color@8.1.1: | ||||
|   version "8.1.1" | ||||
|   resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" | ||||
| @ -8313,12 +8478,16 @@ vscode-jsonrpc@8.2.0: | ||||
|   resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz#f43dfa35fb51e763d17cd94dcca0c9458f35abf9" | ||||
|   integrity sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA== | ||||
|  | ||||
| vscode-jsonrpc@^8.2.1: | ||||
|   version "8.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.1.tgz#a322cc0f1d97f794ffd9c4cd2a898a0bde097f34" | ||||
|   integrity sha512-kdjOSJ2lLIn7r1rtrMbbNCHjyMPfRnowdKjBQ+mGq6NAW5QY2bEZC/khaC5OR8svbbjvLEaIXkOq45e2X9BIbQ== | ||||
| vscode-languageclient@^9.0.1: | ||||
|   version "9.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-9.0.1.tgz#cdfe20267726c8d4db839dc1e9d1816e1296e854" | ||||
|   integrity sha512-JZiimVdvimEuHh5olxhxkht09m3JzUGwggb5eRUkzzJhZ2KjCN0nh55VfiED9oez9DyF8/fz1g1iBV3h+0Z2EA== | ||||
|   dependencies: | ||||
|     minimatch "^5.1.0" | ||||
|     semver "^7.3.7" | ||||
|     vscode-languageserver-protocol "3.17.5" | ||||
|  | ||||
| vscode-languageserver-protocol@^3.17.5: | ||||
| vscode-languageserver-protocol@3.17.5, vscode-languageserver-protocol@^3.17.5: | ||||
|   version "3.17.5" | ||||
|   resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz#864a8b8f390835572f4e13bd9f8313d0e3ac4bea" | ||||
|   integrity sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg== | ||||
| @ -8331,6 +8500,34 @@ vscode-languageserver-types@3.17.5: | ||||
|   resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz#3273676f0cf2eab40b3f44d085acbb7f08a39d8a" | ||||
|   integrity sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg== | ||||
|  | ||||
| vscode-languageserver@^9.0.1: | ||||
|   version "9.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz#500aef82097eb94df90d008678b0b6b5f474015b" | ||||
|   integrity sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g== | ||||
|   dependencies: | ||||
|     vscode-languageserver-protocol "3.17.5" | ||||
|  | ||||
| vscode-test@^0.4.1: | ||||
|   version "0.4.3" | ||||
|   resolved "https://registry.yarnpkg.com/vscode-test/-/vscode-test-0.4.3.tgz#461ebf25fc4bc93d77d982aed556658a2e2b90b8" | ||||
|   integrity sha512-EkMGqBSefZH2MgW65nY05rdRSko15uvzq4VAPM5jVmwYuFQKE7eikKXNJDRxL+OITXHB6pI+a3XqqD32Y3KC5w== | ||||
|   dependencies: | ||||
|     http-proxy-agent "^2.1.0" | ||||
|     https-proxy-agent "^2.2.1" | ||||
|  | ||||
| vscode@^1.1.37: | ||||
|   version "1.1.37" | ||||
|   resolved "https://registry.yarnpkg.com/vscode/-/vscode-1.1.37.tgz#c2a770bee4bb3fff765e2b72c7bcc813b8a6bb0a" | ||||
|   integrity sha512-vJNj6IlN7IJPdMavlQa1KoFB3Ihn06q1AiN3ZFI/HfzPNzbKZWPPuiU+XkpNOfGU5k15m4r80nxNPlM7wcc0wg== | ||||
|   dependencies: | ||||
|     glob "^7.1.2" | ||||
|     http-proxy-agent "^4.0.1" | ||||
|     https-proxy-agent "^5.0.0" | ||||
|     mocha "^5.2.0" | ||||
|     semver "^5.4.1" | ||||
|     source-map-support "^0.5.0" | ||||
|     vscode-test "^0.4.1" | ||||
|  | ||||
| w3c-keyname@^2.2.4: | ||||
|   version "2.2.8" | ||||
|   resolved "https://registry.yarnpkg.com/w3c-keyname/-/w3c-keyname-2.2.8.tgz#7b17c8c6883d4e8b86ac8aba79d39e880f8869c5" | ||||
| @ -8552,7 +8749,7 @@ workerpool@6.2.1: | ||||
|   resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" | ||||
|   integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== | ||||
|  | ||||
| "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: | ||||
| "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": | ||||
|   version "7.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" | ||||
|   integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== | ||||
| @ -8570,6 +8767,15 @@ wrap-ansi@^6.2.0: | ||||
|     string-width "^4.1.0" | ||||
|     strip-ansi "^6.0.0" | ||||
|  | ||||
| wrap-ansi@^7.0.0: | ||||
|   version "7.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" | ||||
|   integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== | ||||
|   dependencies: | ||||
|     ansi-styles "^4.0.0" | ||||
|     string-width "^4.1.0" | ||||
|     strip-ansi "^6.0.0" | ||||
|  | ||||
| wrap-ansi@^8.1.0: | ||||
|   version "8.1.0" | ||||
|   resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" | ||||
| @ -8589,11 +8795,6 @@ ws@8.13.0: | ||||
|   resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" | ||||
|   integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== | ||||
|  | ||||
| ws@^7.0.0: | ||||
|   version "7.5.10" | ||||
|   resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" | ||||
|   integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== | ||||
|  | ||||
| ws@^8.17.0, ws@^8.8.0: | ||||
|   version "8.17.1" | ||||
|   resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b" | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	