diff --git a/packages/cubejs-backend-native/js/index.ts b/packages/cubejs-backend-native/js/index.ts index 077c3de15986f..8bd390d3801a4 100644 --- a/packages/cubejs-backend-native/js/index.ts +++ b/packages/cubejs-backend-native/js/index.ts @@ -122,12 +122,14 @@ export type SQLInterfaceOptions = { export interface TransformConfig { fileName: string; + fileContent: string; transpilers: string[]; compilerId: string; metaData?: { cubeNames: string[]; cubeSymbols: Record>; contextSymbols: Record; + stage: 0 | 1 | 2 | 3; } } @@ -495,11 +497,11 @@ export const getFinalQueryResultMulti = (transformDataArr: Object[], rows: any[] return native.getFinalQueryResultMulti(transformDataArr, rows, responseData); }; -export const transpileJs = async (content: String, metadata: TransformConfig): Promise => { +export const transpileJs = async (transpileRequests: TransformConfig[]): Promise => { const native = loadNative(); if (native.transpileJs) { - return native.transpileJs(content, metadata); + return native.transpileJs(transpileRequests); } throw new Error('TranspileJs native implementation not found!'); diff --git a/packages/cubejs-query-orchestrator/package.json b/packages/cubejs-query-orchestrator/package.json index 6e115020c00e3..9d011e262bf79 100644 --- a/packages/cubejs-query-orchestrator/package.json +++ b/packages/cubejs-query-orchestrator/package.json @@ -34,7 +34,7 @@ "@cubejs-backend/shared": "1.2.27", "csv-write-stream": "^2.0.0", "generic-pool": "^3.8.2", - "lru-cache": "^5.1.1", + "lru-cache": "^11.1.0", "ramda": "^0.27.2" }, "devDependencies": { diff --git a/packages/cubejs-query-orchestrator/src/orchestrator/PreAggregations.ts b/packages/cubejs-query-orchestrator/src/orchestrator/PreAggregations.ts index f15cc56ab286f..bf59b5e3df8b1 100644 --- a/packages/cubejs-query-orchestrator/src/orchestrator/PreAggregations.ts +++ b/packages/cubejs-query-orchestrator/src/orchestrator/PreAggregations.ts @@ -4,7 +4,7 @@ import { getEnv, } from '@cubejs-backend/shared'; import { BaseDriver, InlineTable, } from '@cubejs-backend/base-driver'; import { CubeStoreDriver } from '@cubejs-backend/cubestore-driver'; -import LRUCache from 'lru-cache'; +import { LRUCache } from 'lru-cache'; import { PreAggTableToTempTable, Query, QueryBody, QueryCache, QueryWithParams } from './QueryCache'; import { DriverFactory, DriverFactoryByDataSource } from './DriverFactory'; @@ -282,8 +282,8 @@ export class PreAggregations { this.getQueueEventsBus = options.getQueueEventsBus; this.touchCache = new LRUCache({ max: getEnv('touchPreAggregationCacheMaxCount'), - maxAge: getEnv('touchPreAggregationCacheMaxAge') * 1000, - stale: false, + ttl: getEnv('touchPreAggregationCacheMaxAge') * 1000, + allowStale: false, updateAgeOnGet: false }); } @@ -330,7 +330,7 @@ export class PreAggregations { this.touchTablePersistTime ); } catch (e: unknown) { - this.touchCache.del(tableName); + this.touchCache.delete(tableName); throw e; } diff --git a/packages/cubejs-query-orchestrator/src/orchestrator/QueryCache.ts b/packages/cubejs-query-orchestrator/src/orchestrator/QueryCache.ts index 7f2360b95be65..c518224961d96 100644 --- a/packages/cubejs-query-orchestrator/src/orchestrator/QueryCache.ts +++ b/packages/cubejs-query-orchestrator/src/orchestrator/QueryCache.ts @@ -1,6 +1,6 @@ import crypto from 'crypto'; import csvWriter from 'csv-write-stream'; -import LRUCache from 'lru-cache'; +import { LRUCache } from 'lru-cache'; import { pipeline } from 'stream'; import { getEnv, MaybeCancelablePromise, streamToArray } from '@cubejs-backend/shared'; import { CubeStoreCacheDriver, CubeStoreDriver } from '@cubejs-backend/cubestore-driver'; @@ -909,7 +909,7 @@ export class QueryCache { inMemoryValue.renewalKey !== renewalKey ) || renewedAgo > expiration * 1000 || renewedAgo > inMemoryCacheDisablePeriod ) { - this.memoryCache.del(redisKey); + this.memoryCache.delete(redisKey); } else { this.logger('Found in memory cache entry', { cacheKey, diff --git a/packages/cubejs-schema-compiler/package.json b/packages/cubejs-schema-compiler/package.json index a24829cee22e3..fe880fb202cb3 100644 --- a/packages/cubejs-schema-compiler/package.json +++ b/packages/cubejs-schema-compiler/package.json @@ -49,7 +49,7 @@ "inflection": "^1.12.0", "joi": "^17.8.3", "js-yaml": "^4.1.0", - "lru-cache": "^5.1.1", + "lru-cache": "^11.1.0", "moment-timezone": "^0.5.46", "node-dijkstra": "^2.5.0", "ramda": "^0.27.2", @@ -66,7 +66,6 @@ "@types/babel__traverse": "^7.20.5", "@types/inflection": "^1.5.28", "@types/jest": "^27", - "@types/lru-cache": "^5.1.0", "@types/node": "^18", "@types/ramda": "^0.27.34", "@types/sqlstring": "^2.3.0", diff --git a/packages/cubejs-schema-compiler/src/compiler/CompilerCache.ts b/packages/cubejs-schema-compiler/src/compiler/CompilerCache.ts index 3ec5b0b2c25ab..8e78665ae67b6 100644 --- a/packages/cubejs-schema-compiler/src/compiler/CompilerCache.ts +++ b/packages/cubejs-schema-compiler/src/compiler/CompilerCache.ts @@ -1,4 +1,4 @@ -import LRUCache from 'lru-cache'; +import { LRUCache } from 'lru-cache'; import { QueryCache } from '../adapter/QueryCache'; export class CompilerCache extends QueryCache { @@ -11,13 +11,13 @@ export class CompilerCache extends QueryCache { this.queryCache = new LRUCache({ max: maxQueryCacheSize || 10000, - maxAge: (maxQueryCacheAge * 1000) || 1000 * 60 * 10, + ttl: (maxQueryCacheAge * 1000) || 1000 * 60 * 10, updateAgeOnGet: true }); this.rbacCache = new LRUCache({ max: 10000, - maxAge: 1000 * 60 * 5, // 5 minutes + ttl: 1000 * 60 * 5, // 5 minutes }); } diff --git a/packages/cubejs-schema-compiler/src/compiler/DataSchemaCompiler.js b/packages/cubejs-schema-compiler/src/compiler/DataSchemaCompiler.js index d10ea3ede5a25..eb0fee5e84523 100644 --- a/packages/cubejs-schema-compiler/src/compiler/DataSchemaCompiler.js +++ b/packages/cubejs-schema-compiler/src/compiler/DataSchemaCompiler.js @@ -1,5 +1,7 @@ +import crypto from 'crypto'; import vm from 'vm'; import fs from 'fs'; +import os from 'os'; import path from 'path'; import syntaxCheck from 'syntax-error'; import { parse } from '@babel/parser'; @@ -20,6 +22,21 @@ const moduleFileCache = {}; const JINJA_SYNTAX = /{%|%}|{{|}}/ig; +const getThreadsCount = () => { + const envThreads = getEnv('transpilationWorkerThreadsCount'); + if (envThreads > 0) { + return envThreads; + } + + const cpuCount = os.cpus()?.length; + if (cpuCount) { + // there's no practical boost above 5 threads even if you have more cores. + return Math.min(Math.max(1, cpuCount - 1), 5); + } + + return 3; // Default (like the workerpool do) +}; + export class DataSchemaCompiler { constructor(repository, options = {}) { this.repository = repository; @@ -47,6 +64,7 @@ export class DataSchemaCompiler { this.pythonContext = null; this.workerPool = null; this.compilerId = options.compilerId; + this.compiledScriptCache = options.compiledScriptCache; } compileObjects(compileServices, objects, errorsReport) { @@ -98,6 +116,7 @@ export class DataSchemaCompiler { const transpilationWorkerThreads = getEnv('transpilationWorkerThreads'); const transpilationNative = getEnv('transpilationNative'); + const transpilationNativeThreadsCount = getThreadsCount(); const { compilerId } = this; if (!transpilationNative && transpilationWorkerThreads) { @@ -108,7 +127,11 @@ export class DataSchemaCompiler { ); } - const transpile = async () => { + /** + * @param stage Number + * @returns {Promise<*>} + */ + const transpile = async (stage) => { let cubeNames; let cubeSymbols; let transpilerNames; @@ -143,9 +166,28 @@ export class DataSchemaCompiler { content: ';', }; - await this.transpileJsFile(dummyFile, errorsReport, { cubeNames, cubeSymbols, transpilerNames, contextSymbols: CONTEXT_SYMBOLS, compilerId }); + await this.transpileJsFile(dummyFile, errorsReport, { cubeNames, cubeSymbols, transpilerNames, contextSymbols: CONTEXT_SYMBOLS, compilerId, stage }); + + const nonJsFilesTasks = toCompile.filter(file => !file.fileName.endsWith('.js')) + .map(f => this.transpileFile(f, errorsReport, { transpilerNames, compilerId })); + + const jsFiles = toCompile.filter(file => file.fileName.endsWith('.js')); + let jsChunks; + if (jsFiles.length < transpilationNativeThreadsCount * transpilationNativeThreadsCount) { + jsChunks = [jsFiles]; + } else { + const baseSize = Math.floor(jsFiles.length / transpilationNativeThreadsCount); + jsChunks = []; + for (let i = 0; i < transpilationNativeThreadsCount; i++) { + // For the last part, we take the remaining files so we don't lose the extra ones. + const start = i * baseSize; + const end = (i === transpilationNativeThreadsCount - 1) ? jsFiles.length : start + baseSize; + jsChunks.push(jsFiles.slice(start, end)); + } + } + const JsFilesTasks = jsChunks.map(chunk => this.transpileJsFilesBulk(chunk, errorsReport, { transpilerNames, compilerId })); - results = await Promise.all(toCompile.map(f => this.transpileFile(f, errorsReport, { transpilerNames, compilerId }))); + results = (await Promise.all([...nonJsFilesTasks, ...JsFilesTasks])).flat(); } else if (transpilationWorkerThreads) { results = await Promise.all(toCompile.map(f => this.transpileFile(f, errorsReport, { cubeNames, cubeSymbols, transpilerNames }))); } else { @@ -155,17 +197,17 @@ export class DataSchemaCompiler { return results.filter(f => !!f); }; - const compilePhase = async (compilers) => this.compileCubeFiles(compilers, await transpile(), errorsReport); + const compilePhase = async (compilers, stage) => this.compileCubeFiles(compilers, await transpile(stage), errorsReport); - return compilePhase({ cubeCompilers: this.cubeNameCompilers }) - .then(() => compilePhase({ cubeCompilers: this.preTranspileCubeCompilers.concat([this.viewCompilationGate]) })) + return compilePhase({ cubeCompilers: this.cubeNameCompilers }, 0) + .then(() => compilePhase({ cubeCompilers: this.preTranspileCubeCompilers.concat([this.viewCompilationGate]) }, 1)) .then(() => (this.viewCompilationGate.shouldCompileViews() ? - compilePhase({ cubeCompilers: this.viewCompilers }) + compilePhase({ cubeCompilers: this.viewCompilers }, 2) : Promise.resolve())) .then(() => compilePhase({ cubeCompilers: this.cubeCompilers, contextCompilers: this.contextCompilers, - })) + }, 3)) .then(() => { if (transpilationNative) { // Clean up cache @@ -177,7 +219,7 @@ export class DataSchemaCompiler { return this.transpileJsFile( dummyFile, errorsReport, - { cubeNames: [], cubeSymbols: {}, transpilerNames: [], contextSymbols: {}, compilerId: this.compilerId } + { cubeNames: [], cubeSymbols: {}, transpilerNames: [], contextSymbols: {}, compilerId: this.compilerId, stage: 0 } ); } else if (transpilationWorkerThreads && this.workerPool) { this.workerPool.terminate(); @@ -225,11 +267,50 @@ export class DataSchemaCompiler { } } - async transpileJsFile(file, errorsReport, { cubeNames, cubeSymbols, contextSymbols, transpilerNames, compilerId }) { + /** + * Right now it is used only for transpilation in native, + * so no checks for transpilation type inside this method + */ + async transpileJsFilesBulk(files, errorsReport, { cubeNames, cubeSymbols, contextSymbols, transpilerNames, compilerId, stage }) { + // for bulk processing this data may be optimized even more by passing transpilerNames, compilerId only once for a bulk + // but this requires more complex logic to be implemented in the native side. + // And comparing to the file content sizes, a few bytes of JSON data is not a big deal here + const reqDataArr = files.map(file => ({ + fileName: file.fileName, + fileContent: file.content, + transpilers: transpilerNames, + compilerId, + ...(cubeNames && { + metaData: { + cubeNames, + cubeSymbols, + contextSymbols, + stage + }, + }), + })); + const res = await transpileJs(reqDataArr); + + return files.map((file, index) => { + errorsReport.inFile(file); + if (!res[index]) { // This should not happen in theory but just to be safe + errorsReport.error(`No transpilation result received for the file ${file.fileName}.`); + return undefined; + } + errorsReport.addErrors(res[index].errors); + errorsReport.addWarnings(res[index].warnings); + errorsReport.exitFile(); + + return { ...file, content: res[index].code }; + }); + } + + async transpileJsFile(file, errorsReport, { cubeNames, cubeSymbols, contextSymbols, transpilerNames, compilerId, stage }) { try { if (getEnv('transpilationNative')) { const reqData = { fileName: file.fileName, + fileContent: file.content, transpilers: transpilerNames, compilerId, ...(cubeNames && { @@ -237,17 +318,18 @@ export class DataSchemaCompiler { cubeNames, cubeSymbols, contextSymbols, + stage }, }), }; errorsReport.inFile(file); - const res = await transpileJs(file.content, reqData); - errorsReport.addErrors(res.errors); - errorsReport.addWarnings(res.warnings); + const res = await transpileJs([reqData]); + errorsReport.addErrors(res[0].errors); + errorsReport.addWarnings(res[0].warnings); errorsReport.exitFile(); - return { ...file, content: res.code }; + return { ...file, content: res[0].code }; } else if (getEnv('transpilationWorkerThreads')) { const data = { fileName: file.fileName, @@ -370,6 +452,18 @@ export class DataSchemaCompiler { } } + getJsScript(file) { + const cacheKey = crypto.createHash('md5').update(JSON.stringify(file.content)).digest('hex'); + + if (this.compiledScriptCache.has(cacheKey)) { + return this.compiledScriptCache.get(cacheKey); + } + + const script = new vm.Script(file.content, { filename: file.fileName, timeout: 15000 }); + this.compiledScriptCache.set(cacheKey, script); + return script; + } + compileJsFile(file, errorsReport, cubes, contexts, exports, asyncModules, toCompile, compiledFiles, { doSyntaxCheck } = { doSyntaxCheck: false }) { if (doSyntaxCheck) { // There is no need to run syntax check for data model files @@ -382,7 +476,9 @@ export class DataSchemaCompiler { } try { - vm.runInNewContext(file.content, { + const script = this.getJsScript(file); + + script.runInNewContext({ view: (name, cube) => ( !cube ? this.cubeFactory({ ...name, fileName: file.fileName, isView: true }) : diff --git a/packages/cubejs-schema-compiler/src/compiler/PrepareCompiler.ts b/packages/cubejs-schema-compiler/src/compiler/PrepareCompiler.ts index 57f615c2b7840..d55b2db9d2b1a 100644 --- a/packages/cubejs-schema-compiler/src/compiler/PrepareCompiler.ts +++ b/packages/cubejs-schema-compiler/src/compiler/PrepareCompiler.ts @@ -1,6 +1,8 @@ import { SchemaFileRepository } from '@cubejs-backend/shared'; import { NativeInstance } from '@cubejs-backend/native'; import { v4 as uuidv4 } from 'uuid'; +import { LRUCache } from 'lru-cache'; +import vm from 'vm'; import { CubeValidator } from './CubeValidator'; import { DataSchemaCompiler } from './DataSchemaCompiler'; @@ -32,6 +34,7 @@ export type PrepareCompilerOptions = { standalone?: boolean; headCommitId?: string; adapter?: string; + compiledScriptCache?: LRUCache; }; export const prepareCompiler = (repo: SchemaFileRepository, options: PrepareCompilerOptions = {}) => { @@ -49,6 +52,8 @@ export const prepareCompiler = (repo: SchemaFileRepository, options: PrepareComp const compilerCache = new CompilerCache({ maxQueryCacheSize, maxQueryCacheAge }); const yamlCompiler = new YamlCompiler(cubeSymbols, cubeDictionary, nativeInstance, viewCompiler); + const compiledScriptCache = options.compiledScriptCache || new LRUCache({ max: 250 }); + const transpilers: TranspilerInterface[] = [ new ValidationTranspiler(), new ImportExportTranspiler(), @@ -66,6 +71,7 @@ export const prepareCompiler = (repo: SchemaFileRepository, options: PrepareComp preTranspileCubeCompilers: [cubeSymbols, cubeValidator], transpilers, viewCompilationGate, + compiledScriptCache, viewCompilers: [viewCompiler], cubeCompilers: [cubeEvaluator, joinGraph, metaTransformer], contextCompilers: [contextEvaluator], diff --git a/packages/cubejs-server-core/package.json b/packages/cubejs-server-core/package.json index a6c3c2a297bce..3317460e58411 100644 --- a/packages/cubejs-server-core/package.json +++ b/packages/cubejs-server-core/package.json @@ -46,7 +46,7 @@ "joi": "^17.8.3", "jsonwebtoken": "^9.0.2", "lodash.clonedeep": "^4.5.0", - "lru-cache": "^5.1.1", + "lru-cache": "^11.1.0", "moment": "^2.29.1", "node-fetch": "^2.6.0", "p-limit": "^3.1.0", @@ -67,7 +67,6 @@ "@types/fs-extra": "^9.0.8", "@types/jest": "^27", "@types/jsonwebtoken": "^9.0.2", - "@types/lru-cache": "^5.1.0", "@types/node": "^18", "@types/node-fetch": "^2.5.7", "@types/ramda": "^0.27.34", diff --git a/packages/cubejs-server-core/src/core/CompilerApi.js b/packages/cubejs-server-core/src/core/CompilerApi.js index 71c5517e5976e..739955c331bdf 100644 --- a/packages/cubejs-server-core/src/core/CompilerApi.js +++ b/packages/cubejs-server-core/src/core/CompilerApi.js @@ -1,7 +1,8 @@ import crypto from 'crypto'; import R from 'ramda'; import { createQuery, compile, queryClass, PreAggregations, QueryFactory } from '@cubejs-backend/schema-compiler'; -import { v4 as uuidv4, parse as uuidParse, stringify as uuidStringify } from 'uuid'; +import { v4 as uuidv4, parse as uuidParse } from 'uuid'; +import { LRUCache } from 'lru-cache'; import { NativeInstance } from '@cubejs-backend/native'; export class CompilerApi { @@ -29,6 +30,11 @@ export class CompilerApi { this.sqlCache = options.sqlCache; this.standalone = options.standalone; this.nativeInstance = this.createNativeInstance(); + this.compiledScriptCache = new LRUCache({ + max: options.compilerCacheSize || 250, + ttl: options.maxCompilerCacheKeepAlive, + updateAgeOnGet: options.updateCompilerCacheKeepAlive + }); } setGraphQLSchema(schema) { @@ -83,6 +89,7 @@ export class CompilerApi { allowJsDuplicatePropsInSchema: this.allowJsDuplicatePropsInSchema, standalone: this.standalone, nativeInstance: this.nativeInstance, + compiledScriptCache: this.compiledScriptCache, }); this.queryFactory = await this.createQueryFactory(compilers); diff --git a/packages/cubejs-server-core/src/core/OrchestratorStorage.ts b/packages/cubejs-server-core/src/core/OrchestratorStorage.ts index deb51e40971c6..fba3e8213a091 100644 --- a/packages/cubejs-server-core/src/core/OrchestratorStorage.ts +++ b/packages/cubejs-server-core/src/core/OrchestratorStorage.ts @@ -1,7 +1,16 @@ +import { LRUCache } from 'lru-cache'; import type { OrchestratorApi } from './OrchestratorApi'; export class OrchestratorStorage { - protected readonly storage: Map = new Map(); + protected readonly storage: LRUCache; + + public constructor(options: { compilerCacheSize?: number, maxCompilerCacheKeepAlive?: number, updateCompilerCacheKeepAlive?: boolean } = { compilerCacheSize: 1000 }) { + this.storage = new LRUCache({ + max: options.compilerCacheSize || 250, + ttl: options.maxCompilerCacheKeepAlive, + updateAgeOnGet: options.updateCompilerCacheKeepAlive + }); + } public has(orchestratorId: string) { return this.storage.has(orchestratorId); @@ -20,37 +29,15 @@ export class OrchestratorStorage { } public async testConnections() { - const result = []; - - // eslint-disable-next-line no-restricted-syntax - for (const orchestratorApi of this.storage.values()) { - result.push(orchestratorApi.testConnection()); - } - - return Promise.all(result); + return Promise.all([...this.storage.values()].map(api => api.testConnection())); } public async testOrchestratorConnections() { - const result = []; - - // eslint-disable-next-line no-restricted-syntax - for (const orchestratorApi of this.storage.values()) { - result.push(orchestratorApi.testOrchestratorConnections()); - } - - return Promise.all(result); + return Promise.all([...this.storage.values()].map(api => api.testOrchestratorConnections())); } public async releaseConnections() { - const result = []; - - // eslint-disable-next-line no-restricted-syntax - for (const orchestratorApi of this.storage.values()) { - result.push(orchestratorApi.release()); - } - - await Promise.all(result); - + await Promise.all([...this.storage.values()].map(api => api.release())); this.storage.clear(); } } diff --git a/packages/cubejs-server-core/src/core/server.ts b/packages/cubejs-server-core/src/core/server.ts index de61bda43f981..00877235dc98f 100644 --- a/packages/cubejs-server-core/src/core/server.ts +++ b/packages/cubejs-server-core/src/core/server.ts @@ -1,7 +1,7 @@ /* eslint-disable global-require,no-return-assign */ import crypto from 'crypto'; import fs from 'fs-extra'; -import LRUCache from 'lru-cache'; +import { LRUCache } from 'lru-cache'; import isDocker from 'is-docker'; import pLimit from 'p-limit'; @@ -203,7 +203,7 @@ export class CubejsServerCore { this.compilerCache = new LRUCache({ max: this.options.compilerCacheSize || 250, - maxAge: this.options.maxCompilerCacheKeepAlive, + ttl: this.options.maxCompilerCacheKeepAlive, updateAgeOnGet: this.options.updateCompilerCacheKeepAlive }); @@ -224,7 +224,7 @@ export class CubejsServerCore { // proactively free up old cache values occasionally if (this.options.maxCompilerCacheKeepAlive) { this.maxCompilerCacheKeep = setInterval( - () => this.compilerCache.prune(), + () => this.compilerCache.purgeStale(), this.options.maxCompilerCacheKeepAlive ); } @@ -554,7 +554,7 @@ export class CubejsServerCore { await this.orchestratorStorage.releaseConnections(); this.orchestratorStorage.clear(); - this.compilerCache.reset(); + this.compilerCache.clear(); this.reloadEnvVariables(); @@ -714,6 +714,9 @@ export class CubejsServerCore { standalone: this.standalone, allowNodeRequire: options.allowNodeRequire, fastReload: options.fastReload || getEnv('fastReload'), + compilerCacheSize: this.options.compilerCacheSize || 250, + maxCompilerCacheKeepAlive: this.options.maxCompilerCacheKeepAlive, + updateCompilerCacheKeepAlive: this.options.updateCompilerCacheKeepAlive }, ); } diff --git a/packages/cubejs-templates/src/PackageFetcher.ts b/packages/cubejs-templates/src/PackageFetcher.ts index 88b123223e48c..c5e0d36169ce4 100644 --- a/packages/cubejs-templates/src/PackageFetcher.ts +++ b/packages/cubejs-templates/src/PackageFetcher.ts @@ -16,7 +16,7 @@ export class PackageFetcher { protected repoArchivePath: string; - public constructor(private repo: Repository) { + public constructor(private readonly repo: Repository) { this.tmpFolderPath = path.resolve('.', 'node_modules', '.tmp'); this.init(); @@ -53,7 +53,7 @@ export class PackageFetcher { (await proxyFetch(url)).body.pipe(writer); return new Promise((resolve, reject) => { - writer.on('finish', resolve); + writer.on('finish', resolve as () => void); writer.on('error', reject); }); } diff --git a/yarn.lock b/yarn.lock index fc962405e7d51..805cdfdb06c69 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9601,11 +9601,6 @@ resolved "https://registry.yarnpkg.com/@types/jwk-to-pem/-/jwk-to-pem-2.0.1.tgz#ba6949f447e02cb7bebf101551e3a4dea5f4fde4" integrity sha512-QXmRPhR/LPzvXBHTPfG2BBfMTkNLUD7NyRcPft8m5xFCeANa1BZyLgT0Gw+OxdWx6i1WCpT27EqyggP4UUHMrA== -"@types/lru-cache@^5.1.0": - version "5.1.1" - resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.1.tgz#c48c2e27b65d2a153b19bfc1a317e30872e01eef" - integrity sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw== - "@types/mime@^1": version "1.3.2" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" @@ -17154,7 +17149,7 @@ generate-object-property@^1.0.0: dependencies: is-property "^1.0.0" -generic-pool@*, generic-pool@^3.6.0, generic-pool@^3.8.2: +generic-pool@*, generic-pool@^3.8.2: version "3.9.0" resolved "https://registry.yarnpkg.com/generic-pool/-/generic-pool-3.9.0.tgz#36f4a678e963f4fdb8707eab050823abc4e8f5e4" integrity sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g== @@ -20685,16 +20680,16 @@ lower-case@^2.0.2: dependencies: tslib "^2.0.3" -lru-cache@^10.0.1: - version "10.1.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.1.0.tgz#2098d41c2dc56500e6c88584aa656c84de7d0484" - integrity sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag== - -lru-cache@^10.2.0, lru-cache@^10.2.2: +lru-cache@^10.0.1, lru-cache@^10.2.0, lru-cache@^10.2.2, "lru-cache@^9.1.1 || ^10.0.0": version "10.4.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== +lru-cache@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.1.0.tgz#afafb060607108132dbc1cf8ae661afb69486117" + integrity sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A== + lru-cache@^4.0.1, lru-cache@^4.1.2, lru-cache@^4.1.5: version "4.1.5" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" @@ -20722,13 +20717,6 @@ lru-cache@^7.14.1, lru-cache@^7.7.1: resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== -"lru-cache@^9.1.1 || ^10.0.0": - version "10.0.2" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.2.tgz#34504678cc3266b09b8dfd6fab4e1515258271b7" - integrity sha512-Yj9mA8fPiVgOUpByoTZO5pNrcl5Yk37FcSHsUINpAsaBIEZIuqcCclDZJCVxqQShDsmYX8QG63svJiTbOATZwg== - dependencies: - semver "^7.3.5" - lru.min@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/lru.min/-/lru.min-1.1.1.tgz#146e01e3a183fa7ba51049175de04667d5701f0e"