Compare commits

...

5 Commits

Author SHA1 Message Date
2363010cbc updates
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-06-26 11:38:59 -07:00
bd17bc98d5 cleanup
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-06-26 10:47:07 -07:00
e7a2824cb2 u[dates
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-06-26 10:40:07 -07:00
f77ed3d790 more
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-06-26 05:33:28 -07:00
bc5fdbad43 updates
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-06-26 05:03:35 -07:00
21 changed files with 444 additions and 1028 deletions

View File

@ -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",

View File

@ -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,
}
lspWorker.postMessage({
worker: LspWorker.Kcl,
eventType: LspWorkerEventType.Init,
eventData: initEvent,
})
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)
callback: () => {
setIsLspReady(true)
},
wasmUrl: wasmUrl(),
}
const lspClient = new LanguageServerClient({ client, name: LspWorker.Kcl })
const lsp = new LspServerClient({ worker: LspWorker.Kcl, options })
lsp.startServer()
const lspClient = new LanguageServerClient({
client: lsp,
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,
}
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)
callback: () => {
setIsCopilotReady(true)
},
wasmUrl: wasmUrl(),
}
const lsp = new LspServerClient({ worker: LspWorker.Copilot, options })
lsp.startServer()
const lspClient = new LanguageServerClient({
client,
client: lsp,
name: LspWorker.Copilot,
})
return { lspClient }

View File

@ -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
constructor(context: LspContext) {
this.context = context
}
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)
}
async startServer() {
this.worker = new Worker({ name: this.context.worker })
this.worker.postMessage({
worker: this.context.worker,
eventType: LspWorkerEventType.Init,
eventData: this.context.options,
})
)
this.#fromServer = fromServer
}
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
async startClient() {
const clientOptions: LanguageClientOptions = {
documentSelector: [{ language: 'kcl' }],
diagnosticCollectionName: 'markers',
}
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
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)
}
}
}
async processRequests(): Promise<void> {
for await (const request of this.#fromServer.requests) {
await this.receiveAndSend(request)
try {
await this.client.start()
} catch (error) {
this.client.error(`Start failed`, error, 'force')
}
}
pushAfterInitializeHook(...hooks: (() => Promise<void>)[]): void {
this.afterInitializedHooks.push(...hooks)
deactivate() {
return this.client?.stop()
}
}

View File

@ -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
}
}
}

View File

@ -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
}
}

View File

@ -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)
}
}
}

View File

@ -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*/, '')
}
}

View File

@ -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' }
}

View File

@ -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)
}

View File

@ -122,11 +122,11 @@ 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(
serverCapabilities.completionProvider?.triggerCharacters?.includes(
line.text[pos - line.from - 1]
)
) {

View File

@ -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
}
}

View File

@ -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
}

View File

@ -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(),

View File

@ -33,16 +33,20 @@ export default class Queue<T>
}
}
constructor() {
constructor(stream?: WritableStream<T>) {
const closed = this.#closed
const promises = this.#promises
const resolvers = this.#resolvers
if (stream) {
this.#stream = stream
} else {
this.#stream = new WritableStream({
write(item: T): void {
Queue.#__enqueue(closed, promises, resolvers, item)
},
})
}
}
#add(): void {
return Queue.#__add(this.#promises, this.#resolvers)

View File

@ -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 }

View File

@ -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)
}
}
}

View File

@ -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 {

View File

@ -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)
}
})

View File

@ -19,7 +19,6 @@ import {
createPipeSubstitution,
} from './modifyAst'
import { err } from 'lib/trap'
import { warn } from 'node:console'
beforeAll(async () => {
await initPromise

View File

@ -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
View File

@ -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"