@lage-run/scheduler 1.5.19 → 1.5.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -112,7 +112,7 @@ class SimpleScheduler {
112
112
  }
113
113
  }
114
114
  const poolStats = pool.stats();
115
- await this.options.hasher.cleanup();
115
+ this.options.hasher.cleanup();
116
116
  return {
117
117
  targetRunByStatus,
118
118
  targetRuns: this.targetRuns,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/SimpleScheduler.ts"],"sourcesContent":["import type { CacheOptions } from \"@lage-run/cache\";\nimport type { TargetHasher } from \"@lage-run/hasher\";\nimport type { Logger } from \"@lage-run/logger\";\nimport type { TargetRunnerPickerOptions } from \"@lage-run/runners\";\nimport { TargetRunnerPicker } from \"@lage-run/runners\";\nimport type { SchedulerRunResults, SchedulerRunSummary, TargetRunSummary, TargetScheduler } from \"@lage-run/scheduler-types\";\nimport type { TargetGraph } from \"@lage-run/target-graph\";\nimport { type Target, getStartTargetId, sortTargetsByPriority } from \"@lage-run/target-graph\";\nimport type { Pool } from \"@lage-run/worker-threads-pool\";\nimport { AggregatedPool } from \"@lage-run/worker-threads-pool\";\nimport type { MessagePort } from \"worker_threads\";\nimport { categorizeTargetRuns } from \"./categorizeTargetRuns.js\";\nimport { formatBytes } from \"./formatBytes.js\";\nimport type { WorkerResult } from \"./WrappedTarget.js\";\nimport { WrappedTarget } from \"./WrappedTarget.js\";\n\nexport interface SimpleSchedulerOptions {\n logger: Logger;\n concurrency: number;\n continueOnError: boolean;\n shouldCache: boolean;\n shouldResetCache: boolean;\n workerData: {\n runners: TargetRunnerPickerOptions;\n root: string;\n taskArgs: string[];\n skipLocalCache?: boolean;\n cacheOptions?: CacheOptions;\n };\n maxWorkersPerTask: Map<string, number>;\n pool?: Pool; // for testing\n workerIdleMemoryLimit: number; // in bytes\n hasher: TargetHasher;\n onMessage?: (message: any, postMessage: MessagePort[\"postMessage\"]) => void;\n}\n\n/**\n * Simple scheduler that runs all targets in a promise graph using p-graph library.\n *\n * Some characteristics:\n * 1. Can cache results of target runs via the cache provider.\n * 2. Takes a TargetRunner, a CacheProvider, a TargetHasher and a Logger as constructor parameters (dependency injection).\n * 3. Directly constructs new WrappedTarget, which provides the call to caching and logging.\n *\n * Roadmap / future enhancements:\n * 1. Allow for multiple kinds of runner (currently only ONE is supported, and it is applied to all targets)\n *\n */\nexport class SimpleScheduler implements TargetScheduler<WorkerResult> {\n public readonly targetRuns: Map<string, WrappedTarget> = new Map();\n private rerunTargets: Set<string> = new Set();\n private abortController: AbortController = new AbortController();\n private abortSignal: AbortSignal = this.abortController.signal;\n private pool: Pool;\n public readonly runnerPicker: TargetRunnerPicker;\n\n constructor(private options: SimpleSchedulerOptions) {\n this.pool =\n options.pool ??\n new AggregatedPool({\n logger: options.logger,\n maxWorkersByGroup: options.maxWorkersPerTask,\n groupBy: ({ target }) => target.task,\n maxWorkers: options.concurrency,\n script: require.resolve(\"./workers/targetWorker\"),\n workerOptions: {\n stdout: true,\n stderr: true,\n workerData: { ...options.workerData, shouldCache: options.shouldCache, shouldResetCache: options.shouldResetCache },\n },\n workerIdleMemoryLimit: options.workerIdleMemoryLimit, // in bytes\n });\n\n this.runnerPicker = new TargetRunnerPicker(options.workerData.runners);\n }\n\n private getTargetsByPriority(): Target[] {\n return sortTargetsByPriority([...this.targetRuns.values()].map((run) => run.target));\n }\n\n /**\n * The job of the run method is to:\n * 1. Convert the target graph into a promise graph.\n * 2. Create a promise graph of all targets\n * 3. Pass the continueOnError option to the promise graph runner.\n */\n public async run(root: string, targetGraph: TargetGraph, shouldRerun = false): Promise<SchedulerRunSummary<WorkerResult>> {\n const startTime: [number, number] = process.hrtime();\n\n const { continueOnError, logger, shouldCache } = this.options;\n\n logger.verbose(\"\", {\n schedulerRun: {\n startTime,\n },\n });\n\n const { pool, abortController } = this;\n\n const { targets } = targetGraph;\n\n for (const target of targets.values()) {\n let targetRun: WrappedTarget;\n\n const prevTargetRun = this.targetRuns.get(target.id);\n if (prevTargetRun) {\n targetRun = prevTargetRun;\n\n // If previous run has been successful, then we may want to rerun\n if (prevTargetRun.successful && shouldRerun) {\n this.markTargetAndDependentsPending(target.id);\n } else if (prevTargetRun.waiting && shouldRerun) {\n this.rerunTargets.add(targetRun.target.id);\n } else if (!prevTargetRun.successful) {\n // If previous run has failed, we should rerun\n this.markTargetAndDependentsPending(target.id);\n }\n } else {\n targetRun = new WrappedTarget({\n target,\n root,\n logger,\n shouldCache,\n continueOnError,\n abortController,\n pool,\n hasher: this.options.hasher,\n onMessage: this.options.onMessage,\n });\n }\n\n this.targetRuns.set(target.id, targetRun);\n }\n\n let results: SchedulerRunResults = \"failed\";\n let error: string | undefined;\n let duration: [number, number] = [0, 0];\n let targetRunByStatus: TargetRunSummary;\n\n try {\n await this.scheduleReadyTargets();\n } catch (e) {\n error = e instanceof Error ? e.message : String(e);\n } finally {\n duration = process.hrtime(startTime);\n targetRunByStatus = categorizeTargetRuns(this.targetRuns.values());\n\n if (\n targetRunByStatus.failed.length +\n targetRunByStatus.aborted.length +\n targetRunByStatus.pending.length +\n targetRunByStatus.running.length ===\n 0\n ) {\n results = \"success\";\n }\n }\n\n const poolStats = pool.stats();\n\n await this.options.hasher.cleanup();\n\n return {\n targetRunByStatus,\n targetRuns: this.targetRuns,\n duration,\n startTime,\n results,\n error,\n workerRestarts: poolStats.workerRestarts, // number of times a worker was restarted due to memory usage\n maxWorkerMemoryUsage: poolStats.maxWorkerMemoryUsage, // max memory usage of a worker in bytes\n };\n }\n\n /**\n * Used by consumers of the scheduler to notify that the inputs to the target has changed\n */\n private markTargetAndDependentsPending(targetId: string): void {\n const queue = [targetId];\n while (queue.length > 0) {\n const current = queue.shift()!;\n\n if (this.targetRuns.has(current)) {\n const targetRun = this.targetRuns.get(current)!;\n\n if (targetRun.status !== \"pending\") {\n targetRun.reset();\n this.rerunTargets.add(targetRun.target.id);\n const dependents = targetRun.target.dependents;\n for (const dependent of dependents) {\n queue.push(dependent);\n }\n }\n }\n }\n }\n\n private getReadyTargets(): WrappedTarget[] {\n const readyTargets: Set<WrappedTarget> = new Set();\n\n for (const target of this.getTargetsByPriority()) {\n // Skip the start target\n if (target.id === getStartTargetId()) {\n continue;\n }\n\n const targetRun = this.targetRuns.get(target.id)!;\n\n // If the target is already running, then we can't run it again\n if (targetRun.status === \"pending\") {\n const targetDeps = targetRun.target.dependencies;\n\n // Target is only ready when all its deps are \"successful\" or that it is a root target\n const ready = targetDeps.every((dep) => {\n const fromTarget = this.targetRuns.get(dep)!;\n return fromTarget.successful || dep === getStartTargetId();\n });\n\n if (ready) {\n readyTargets.add(targetRun);\n }\n }\n }\n\n return [...readyTargets];\n }\n\n private isAllDone(): boolean {\n for (const t of this.targetRuns.values()) {\n if (t.status !== \"skipped\" && t.status !== \"success\" && t.target.id !== getStartTargetId()) {\n return false;\n }\n }\n\n return true;\n }\n\n private async scheduleReadyTargets(): Promise<void> {\n if (this.isAllDone() || this.abortSignal.aborted) {\n return Promise.resolve();\n }\n\n this.options.logger.silly(`Max Worker Memory Usage: ${formatBytes(this.pool.stats().maxWorkerMemoryUsage)}`);\n\n const promises: Promise<any>[] = [];\n\n for (const nextTarget of this.getReadyTargets()) {\n const runPromise = this.#generateTargetRunPromise(nextTarget);\n promises.push(runPromise);\n }\n\n await Promise.all(promises);\n }\n\n private logProgress(): void {\n const targetRunByStatus = categorizeTargetRuns(this.targetRuns.values());\n const total = [...this.targetRuns.values()].filter((t) => !t.target.hidden).length;\n\n this.options.logger.verbose(\"\", {\n poolStats: this.pool.stats(),\n progress: {\n waiting: targetRunByStatus.pending.length + targetRunByStatus.queued.length,\n completed:\n targetRunByStatus.aborted.length +\n targetRunByStatus.failed.length +\n targetRunByStatus.skipped.length +\n targetRunByStatus.success.length,\n total,\n },\n });\n }\n\n async #generateTargetRunPromise(target: WrappedTarget) {\n let runError: unknown | undefined;\n\n if (!target.successful || this.rerunTargets.has(target.target.id)) {\n // This do-while loop only runs again if something causes this target to rerun (asynchronously triggering a re-run)\n do {\n this.rerunTargets.delete(target.target.id);\n target.onQueued();\n\n try {\n let shouldRun = true;\n\n try {\n const runner = await this.runnerPicker.pick(target.target);\n shouldRun = await runner.shouldRun(target.target);\n } catch (e) {\n // pass - default to run anyway\n }\n\n if (shouldRun) {\n await target.run();\n } else {\n target.onSkipped();\n }\n } catch (e) {\n runError = e;\n }\n } while (this.rerunTargets.has(target.target.id));\n\n // if a continue option is set, this merely records what errors have been encountered\n // it'll continue down the execution until all the tasks that still works\n if (runError && !this.options?.continueOnError) {\n if (!this.options?.continueOnError) {\n // immediately reject, if not using \"continue\" option\n throw runError;\n }\n }\n }\n\n this.logProgress();\n\n // finally do another round of scheduling to run next round of targets\n await this.scheduleReadyTargets();\n }\n\n public async cleanup(): Promise<void> {\n this.options.logger.silly(`Max Worker Memory Usage: ${formatBytes(this.pool.stats().maxWorkerMemoryUsage)}`);\n await this.pool.close();\n }\n\n /**\n * Abort the scheduler using the abort controller.\n */\n public abort(): void {\n this.abortController.abort();\n }\n}\n"],"names":["SimpleScheduler","getTargetsByPriority","sortTargetsByPriority","targetRuns","values","map","run","target","root","targetGraph","shouldRerun","startTime","process","hrtime","continueOnError","logger","shouldCache","options","verbose","schedulerRun","pool","abortController","targets","targetRun","prevTargetRun","get","id","successful","markTargetAndDependentsPending","waiting","rerunTargets","add","WrappedTarget","hasher","onMessage","set","results","error","duration","targetRunByStatus","scheduleReadyTargets","e","Error","message","String","categorizeTargetRuns","failed","length","aborted","pending","running","poolStats","stats","cleanup","workerRestarts","maxWorkerMemoryUsage","targetId","queue","current","shift","has","status","reset","dependents","dependent","push","getReadyTargets","readyTargets","Set","getStartTargetId","targetDeps","dependencies","ready","every","dep","fromTarget","isAllDone","t","abortSignal","Promise","resolve","silly","formatBytes","promises","nextTarget","runPromise","all","logProgress","total","filter","hidden","progress","queued","completed","skipped","success","close","abort","runnerPicker","Map","AbortController","signal","AggregatedPool","maxWorkersByGroup","maxWorkersPerTask","groupBy","task","maxWorkers","concurrency","script","require","workerOptions","stdout","stderr","workerData","shouldResetCache","workerIdleMemoryLimit","TargetRunnerPicker","runners","runError","delete","onQueued","shouldRun","runner","pick","onSkipped"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/SimpleScheduler.ts"],"sourcesContent":["import type { CacheOptions } from \"@lage-run/cache\";\nimport type { TargetHasher } from \"@lage-run/hasher\";\nimport type { Logger } from \"@lage-run/logger\";\nimport type { TargetRunnerPickerOptions } from \"@lage-run/runners\";\nimport { TargetRunnerPicker } from \"@lage-run/runners\";\nimport type { SchedulerRunResults, SchedulerRunSummary, TargetRunSummary, TargetScheduler } from \"@lage-run/scheduler-types\";\nimport type { TargetGraph } from \"@lage-run/target-graph\";\nimport { type Target, getStartTargetId, sortTargetsByPriority } from \"@lage-run/target-graph\";\nimport type { Pool } from \"@lage-run/worker-threads-pool\";\nimport { AggregatedPool } from \"@lage-run/worker-threads-pool\";\nimport type { MessagePort } from \"worker_threads\";\nimport { categorizeTargetRuns } from \"./categorizeTargetRuns.js\";\nimport { formatBytes } from \"./formatBytes.js\";\nimport type { WorkerResult } from \"./WrappedTarget.js\";\nimport { WrappedTarget } from \"./WrappedTarget.js\";\n\nexport interface SimpleSchedulerOptions {\n logger: Logger;\n concurrency: number;\n continueOnError: boolean;\n shouldCache: boolean;\n shouldResetCache: boolean;\n workerData: {\n runners: TargetRunnerPickerOptions;\n root: string;\n taskArgs: string[];\n skipLocalCache?: boolean;\n cacheOptions?: CacheOptions;\n };\n maxWorkersPerTask: Map<string, number>;\n pool?: Pool; // for testing\n workerIdleMemoryLimit: number; // in bytes\n hasher: TargetHasher;\n onMessage?: (message: any, postMessage: MessagePort[\"postMessage\"]) => void;\n}\n\n/**\n * Simple scheduler that runs all targets in a promise graph using p-graph library.\n *\n * Some characteristics:\n * 1. Can cache results of target runs via the cache provider.\n * 2. Takes a TargetRunner, a CacheProvider, a TargetHasher and a Logger as constructor parameters (dependency injection).\n * 3. Directly constructs new WrappedTarget, which provides the call to caching and logging.\n *\n * Roadmap / future enhancements:\n * 1. Allow for multiple kinds of runner (currently only ONE is supported, and it is applied to all targets)\n *\n */\nexport class SimpleScheduler implements TargetScheduler<WorkerResult> {\n public readonly targetRuns: Map<string, WrappedTarget> = new Map();\n private rerunTargets: Set<string> = new Set();\n private abortController: AbortController = new AbortController();\n private abortSignal: AbortSignal = this.abortController.signal;\n private pool: Pool;\n public readonly runnerPicker: TargetRunnerPicker;\n\n constructor(private options: SimpleSchedulerOptions) {\n this.pool =\n options.pool ??\n new AggregatedPool({\n logger: options.logger,\n maxWorkersByGroup: options.maxWorkersPerTask,\n groupBy: ({ target }) => target.task,\n maxWorkers: options.concurrency,\n script: require.resolve(\"./workers/targetWorker\"),\n workerOptions: {\n stdout: true,\n stderr: true,\n workerData: { ...options.workerData, shouldCache: options.shouldCache, shouldResetCache: options.shouldResetCache },\n },\n workerIdleMemoryLimit: options.workerIdleMemoryLimit, // in bytes\n });\n\n this.runnerPicker = new TargetRunnerPicker(options.workerData.runners);\n }\n\n private getTargetsByPriority(): Target[] {\n return sortTargetsByPriority([...this.targetRuns.values()].map((run) => run.target));\n }\n\n /**\n * The job of the run method is to:\n * 1. Convert the target graph into a promise graph.\n * 2. Create a promise graph of all targets\n * 3. Pass the continueOnError option to the promise graph runner.\n */\n public async run(root: string, targetGraph: TargetGraph, shouldRerun = false): Promise<SchedulerRunSummary<WorkerResult>> {\n const startTime: [number, number] = process.hrtime();\n\n const { continueOnError, logger, shouldCache } = this.options;\n\n logger.verbose(\"\", {\n schedulerRun: {\n startTime,\n },\n });\n\n const { pool, abortController } = this;\n\n const { targets } = targetGraph;\n\n for (const target of targets.values()) {\n let targetRun: WrappedTarget;\n\n const prevTargetRun = this.targetRuns.get(target.id);\n if (prevTargetRun) {\n targetRun = prevTargetRun;\n\n // If previous run has been successful, then we may want to rerun\n if (prevTargetRun.successful && shouldRerun) {\n this.markTargetAndDependentsPending(target.id);\n } else if (prevTargetRun.waiting && shouldRerun) {\n this.rerunTargets.add(targetRun.target.id);\n } else if (!prevTargetRun.successful) {\n // If previous run has failed, we should rerun\n this.markTargetAndDependentsPending(target.id);\n }\n } else {\n targetRun = new WrappedTarget({\n target,\n root,\n logger,\n shouldCache,\n continueOnError,\n abortController,\n pool,\n hasher: this.options.hasher,\n onMessage: this.options.onMessage,\n });\n }\n\n this.targetRuns.set(target.id, targetRun);\n }\n\n let results: SchedulerRunResults = \"failed\";\n let error: string | undefined;\n let duration: [number, number] = [0, 0];\n let targetRunByStatus: TargetRunSummary;\n\n try {\n await this.scheduleReadyTargets();\n } catch (e) {\n error = e instanceof Error ? e.message : String(e);\n } finally {\n duration = process.hrtime(startTime);\n targetRunByStatus = categorizeTargetRuns(this.targetRuns.values());\n\n if (\n targetRunByStatus.failed.length +\n targetRunByStatus.aborted.length +\n targetRunByStatus.pending.length +\n targetRunByStatus.running.length ===\n 0\n ) {\n results = \"success\";\n }\n }\n\n const poolStats = pool.stats();\n\n this.options.hasher.cleanup();\n\n return {\n targetRunByStatus,\n targetRuns: this.targetRuns,\n duration,\n startTime,\n results,\n error,\n workerRestarts: poolStats.workerRestarts, // number of times a worker was restarted due to memory usage\n maxWorkerMemoryUsage: poolStats.maxWorkerMemoryUsage, // max memory usage of a worker in bytes\n };\n }\n\n /**\n * Used by consumers of the scheduler to notify that the inputs to the target has changed\n */\n private markTargetAndDependentsPending(targetId: string): void {\n const queue = [targetId];\n while (queue.length > 0) {\n const current = queue.shift()!;\n\n if (this.targetRuns.has(current)) {\n const targetRun = this.targetRuns.get(current)!;\n\n if (targetRun.status !== \"pending\") {\n targetRun.reset();\n this.rerunTargets.add(targetRun.target.id);\n const dependents = targetRun.target.dependents;\n for (const dependent of dependents) {\n queue.push(dependent);\n }\n }\n }\n }\n }\n\n private getReadyTargets(): WrappedTarget[] {\n const readyTargets: Set<WrappedTarget> = new Set();\n\n for (const target of this.getTargetsByPriority()) {\n // Skip the start target\n if (target.id === getStartTargetId()) {\n continue;\n }\n\n const targetRun = this.targetRuns.get(target.id)!;\n\n // If the target is already running, then we can't run it again\n if (targetRun.status === \"pending\") {\n const targetDeps = targetRun.target.dependencies;\n\n // Target is only ready when all its deps are \"successful\" or that it is a root target\n const ready = targetDeps.every((dep) => {\n const fromTarget = this.targetRuns.get(dep)!;\n return fromTarget.successful || dep === getStartTargetId();\n });\n\n if (ready) {\n readyTargets.add(targetRun);\n }\n }\n }\n\n return [...readyTargets];\n }\n\n private isAllDone(): boolean {\n for (const t of this.targetRuns.values()) {\n if (t.status !== \"skipped\" && t.status !== \"success\" && t.target.id !== getStartTargetId()) {\n return false;\n }\n }\n\n return true;\n }\n\n private async scheduleReadyTargets(): Promise<void> {\n if (this.isAllDone() || this.abortSignal.aborted) {\n return Promise.resolve();\n }\n\n this.options.logger.silly(`Max Worker Memory Usage: ${formatBytes(this.pool.stats().maxWorkerMemoryUsage)}`);\n\n const promises: Promise<any>[] = [];\n\n for (const nextTarget of this.getReadyTargets()) {\n const runPromise = this.#generateTargetRunPromise(nextTarget);\n promises.push(runPromise);\n }\n\n await Promise.all(promises);\n }\n\n private logProgress(): void {\n const targetRunByStatus = categorizeTargetRuns(this.targetRuns.values());\n const total = [...this.targetRuns.values()].filter((t) => !t.target.hidden).length;\n\n this.options.logger.verbose(\"\", {\n poolStats: this.pool.stats(),\n progress: {\n waiting: targetRunByStatus.pending.length + targetRunByStatus.queued.length,\n completed:\n targetRunByStatus.aborted.length +\n targetRunByStatus.failed.length +\n targetRunByStatus.skipped.length +\n targetRunByStatus.success.length,\n total,\n },\n });\n }\n\n async #generateTargetRunPromise(target: WrappedTarget) {\n let runError: unknown | undefined;\n\n if (!target.successful || this.rerunTargets.has(target.target.id)) {\n // This do-while loop only runs again if something causes this target to rerun (asynchronously triggering a re-run)\n do {\n this.rerunTargets.delete(target.target.id);\n target.onQueued();\n\n try {\n let shouldRun = true;\n\n try {\n const runner = await this.runnerPicker.pick(target.target);\n shouldRun = await runner.shouldRun(target.target);\n } catch (e) {\n // pass - default to run anyway\n }\n\n if (shouldRun) {\n await target.run();\n } else {\n target.onSkipped();\n }\n } catch (e) {\n runError = e;\n }\n } while (this.rerunTargets.has(target.target.id));\n\n // if a continue option is set, this merely records what errors have been encountered\n // it'll continue down the execution until all the tasks that still works\n if (runError && !this.options?.continueOnError) {\n if (!this.options?.continueOnError) {\n // immediately reject, if not using \"continue\" option\n throw runError;\n }\n }\n }\n\n this.logProgress();\n\n // finally do another round of scheduling to run next round of targets\n await this.scheduleReadyTargets();\n }\n\n public async cleanup(): Promise<void> {\n this.options.logger.silly(`Max Worker Memory Usage: ${formatBytes(this.pool.stats().maxWorkerMemoryUsage)}`);\n await this.pool.close();\n }\n\n /**\n * Abort the scheduler using the abort controller.\n */\n public abort(): void {\n this.abortController.abort();\n }\n}\n"],"names":["SimpleScheduler","getTargetsByPriority","sortTargetsByPriority","targetRuns","values","map","run","target","root","targetGraph","shouldRerun","startTime","process","hrtime","continueOnError","logger","shouldCache","options","verbose","schedulerRun","pool","abortController","targets","targetRun","prevTargetRun","get","id","successful","markTargetAndDependentsPending","waiting","rerunTargets","add","WrappedTarget","hasher","onMessage","set","results","error","duration","targetRunByStatus","scheduleReadyTargets","e","Error","message","String","categorizeTargetRuns","failed","length","aborted","pending","running","poolStats","stats","cleanup","workerRestarts","maxWorkerMemoryUsage","targetId","queue","current","shift","has","status","reset","dependents","dependent","push","getReadyTargets","readyTargets","Set","getStartTargetId","targetDeps","dependencies","ready","every","dep","fromTarget","isAllDone","t","abortSignal","Promise","resolve","silly","formatBytes","promises","nextTarget","runPromise","all","logProgress","total","filter","hidden","progress","queued","completed","skipped","success","close","abort","runnerPicker","Map","AbortController","signal","AggregatedPool","maxWorkersByGroup","maxWorkersPerTask","groupBy","task","maxWorkers","concurrency","script","require","workerOptions","stdout","stderr","workerData","shouldResetCache","workerIdleMemoryLimit","TargetRunnerPicker","runners","runError","delete","onQueued","shouldRun","runner","pick","onSkipped"],"mappings":"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"}
@@ -228,6 +228,8 @@ class WrappedTarget {
228
228
  type: "hash",
229
229
  hash
230
230
  });
231
+ }).catch((e)=>{
232
+ logger.warn(`Failed to hash target ${target.id}: ${e instanceof Error ? e.message : String(e)}`);
231
233
  });
232
234
  } else if (this.options.onMessage) {
233
235
  this.options.onMessage(data, postMessage);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/WrappedTarget.ts"],"sourcesContent":["import type { TargetHasher } from \"@lage-run/hasher\";\nimport type { Logger } from \"@lage-run/logger\";\nimport { type LogEntry, LogLevel } from \"@lage-run/logger\";\nimport type { TargetRun, TargetStatus } from \"@lage-run/scheduler-types\";\nimport { getStartTargetId, type Target } from \"@lage-run/target-graph\";\nimport type { Pool } from \"@lage-run/worker-threads-pool\";\nimport fs from \"fs\";\nimport { mkdir, writeFile } from \"fs/promises\";\nimport path from \"path\";\nimport type { MessagePort } from \"worker_threads\";\nimport { bufferTransform } from \"./bufferTransform.js\";\nimport { getLageOutputCacheLocation } from \"./getLageOutputCacheLocation.js\";\n\nexport interface WrappedTargetOptions {\n root: string;\n target: Target;\n logger: Logger;\n shouldCache: boolean;\n continueOnError: boolean;\n abortController: AbortController;\n pool: Pool;\n hasher: TargetHasher;\n onMessage?: (message: any, postMessage: MessagePort[\"postMessage\"]) => void;\n}\n\nexport interface WorkerResult {\n stdoutBuffer: string;\n stderrBuffer: string;\n skipped: boolean;\n hash: string;\n value: unknown;\n id: string;\n}\n\n/**\n * Wraps a target with additional functionality:\n * 1. Caching\n * 2. Logging\n * 3. Abort signal\n * 4. Continue on error\n */\nexport class WrappedTarget implements TargetRun<WorkerResult> {\n #status: TargetStatus = \"pending\";\n #result: WorkerResult | undefined;\n public queueTime: [number, number] = [0, 0];\n public startTime: [number, number] = [0, 0];\n public duration: [number, number] = [0, 0];\n public target: Target;\n public threadId = 0;\n\n public get result(): WorkerResult | undefined {\n return this.#result;\n }\n\n public get status(): TargetStatus {\n return this.#status;\n }\n\n public get successful(): boolean {\n return this.#status === \"skipped\" || this.#status === \"success\";\n }\n\n public get waiting(): boolean {\n return this.#status === \"pending\" || this.#status === \"queued\";\n }\n\n constructor(public options: WrappedTargetOptions) {\n this.target = options.target;\n\n if (this.target.id === getStartTargetId()) {\n this.#status = \"success\";\n }\n\n this.options.logger.info(\"\", { target: this.target, status: this.status });\n }\n\n public onQueued(): void {\n this.#status = \"queued\";\n this.queueTime = process.hrtime();\n this.options.logger.info(\"\", { target: this.target, status: \"queued\" });\n }\n\n private onAbort(): void {\n this.#status = \"aborted\";\n this.options.logger.info(\"\", { target: this.target, status: \"aborted\", threadId: this.threadId });\n }\n\n private onStart(threadId: number): void {\n if (this.status !== \"running\") {\n this.threadId = threadId;\n this.#status = \"running\";\n this.startTime = process.hrtime();\n this.options.logger.info(\"\", { target: this.target, status: \"running\", threadId });\n }\n }\n\n private onComplete(): void {\n this.#status = \"success\";\n this.options.logger.info(\"\", {\n target: this.target,\n status: \"success\",\n duration: this.duration,\n threadId: this.threadId,\n });\n }\n\n private onFail(): void {\n this.#status = \"failed\";\n this.options.logger.info(\"\", {\n target: this.target,\n status: \"failed\",\n duration: this.duration,\n threadId: this.threadId,\n });\n\n if (!this.options.continueOnError && this.options.abortController) {\n this.options.abortController.abort();\n }\n }\n\n public onSkipped(hash?: string | undefined): void {\n this.#status = \"skipped\";\n\n if (hash) {\n this.options.logger.info(\"\", {\n target: this.target,\n status: \"skipped\",\n duration: this.duration,\n hash,\n threadId: this.threadId,\n });\n }\n }\n\n public async run(): Promise<WorkerResult | undefined> {\n const { target, logger, shouldCache, abortController, root } = this.options;\n\n const abortSignal = abortController.signal;\n\n if (abortSignal.aborted) {\n this.onStart(0);\n this.onAbort();\n return;\n }\n\n try {\n this.#result = await this.runInPool();\n\n const cacheEnabled = target.cache && shouldCache && this.#result.hash;\n // Save output if cache is enabled & cache is hit\n if (!this.#result.skipped && cacheEnabled) {\n const outputLocation = getLageOutputCacheLocation(root, this.#result.hash);\n const outputPath = path.dirname(outputLocation);\n await mkdir(outputPath, { recursive: true });\n\n const output = `${this.#result.stdoutBuffer}\\n${this.#result.stderrBuffer}`;\n\n await writeFile(outputLocation, output);\n\n logger.verbose(`>> Saved cache - ${this.#result.hash}`, { target });\n }\n\n if (this.#result.skipped) {\n const { hash } = this.#result;\n\n const cachedOutputFile = getLageOutputCacheLocation(root, hash ?? \"\");\n\n const shouldShowCachedOutput = fs.existsSync(cachedOutputFile);\n if (shouldShowCachedOutput) {\n const cachedOutput = fs.readFileSync(cachedOutputFile, \"utf8\");\n logger.verbose(\">> Replaying cached output\", { target });\n logger.verbose(cachedOutput.trim(), { target });\n }\n\n this.onSkipped(hash);\n } else {\n this.onComplete();\n }\n\n return this.#result;\n } catch (e) {\n if (e instanceof Error) {\n logger.error(String(e), { target });\n }\n\n if (abortSignal.aborted) {\n this.onAbort();\n } else {\n this.onFail();\n }\n\n throw e;\n }\n }\n\n private async runInPool(): Promise<WorkerResult> {\n const { target, logger, abortController, pool } = this.options;\n const abortSignal = abortController.signal;\n\n let releaseStdout: any;\n let releaseStderr: any;\n\n const bufferStdout = bufferTransform();\n const bufferStderr = bufferTransform();\n\n let msgHandler: (data: LogEntry<any> & { type: string }) => void;\n\n const result = await (pool.exec(\n { target },\n target.weight ?? 1,\n (worker, stdout, stderr) => {\n const postMessage = worker.postMessage.bind(worker);\n\n msgHandler = (data) => {\n if (data.type === \"log\") {\n logger.log(data.level, data.msg, { target, threadId: worker.threadId });\n } else if (data.type === \"hash\") {\n void this.options.hasher.hash(target).then((hash) => {\n worker.postMessage({ type: \"hash\", hash });\n });\n } else if (this.options.onMessage) {\n this.options.onMessage(data, postMessage);\n }\n };\n\n worker.on(\"message\", msgHandler);\n\n const threadId = worker.threadId;\n\n this.onStart(threadId);\n\n stdout.pipe(bufferStdout.transform);\n stderr.pipe(bufferStderr.transform);\n\n const releaseStdoutStream = logger.stream(LogLevel.verbose, stdout, { target, threadId });\n\n releaseStdout = () => {\n releaseStdoutStream();\n stdout.unpipe(bufferStdout.transform);\n };\n\n const releaseStderrStream = logger.stream(LogLevel.verbose, stderr, { target, threadId });\n\n releaseStderr = () => {\n releaseStderrStream();\n stderr.unpipe(bufferStderr.transform);\n };\n },\n (worker) => {\n worker.off(\"message\", msgHandler);\n this.duration = process.hrtime(this.startTime);\n releaseStdout();\n releaseStderr();\n },\n abortSignal,\n target.priority\n ) as Promise<{ value?: unknown; skipped: boolean; hash: string; id: string }>);\n\n return {\n stdoutBuffer: bufferStdout.buffer,\n stderrBuffer: bufferStderr.buffer,\n skipped: result?.skipped,\n hash: result?.hash,\n value: result?.value,\n id: result?.id,\n };\n }\n\n /**\n * A JSON representation of this wrapped target, used in Jest snapshots.\n *\n * Skips the unpredictable properties of the wrapped target like the startTime and duration.\n */\n public toJSON(): {\n target: string;\n status: TargetStatus;\n } {\n return {\n target: this.target.id,\n status: this.status,\n };\n }\n\n /**\n * Reset the state of this wrapped target.\n */\n public reset(): void {\n this.#result = undefined;\n this.#status = \"pending\";\n }\n}\n"],"names":["WrappedTarget","result","status","successful","waiting","onQueued","queueTime","process","hrtime","options","logger","info","target","onAbort","threadId","onStart","startTime","onComplete","duration","onFail","continueOnError","abortController","abort","onSkipped","hash","run","shouldCache","root","abortSignal","signal","aborted","runInPool","cacheEnabled","cache","skipped","outputLocation","getLageOutputCacheLocation","outputPath","path","dirname","mkdir","recursive","output","stdoutBuffer","stderrBuffer","writeFile","verbose","cachedOutputFile","shouldShowCachedOutput","fs","existsSync","cachedOutput","readFileSync","trim","e","Error","error","String","pool","releaseStdout","releaseStderr","bufferStdout","bufferTransform","bufferStderr","msgHandler","exec","weight","worker","stdout","stderr","postMessage","bind","data","type","log","level","msg","hasher","then","onMessage","on","pipe","transform","releaseStdoutStream","stream","LogLevel","unpipe","releaseStderrStream","off","priority","buffer","value","id","toJSON","reset","undefined","getStartTargetId"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/WrappedTarget.ts"],"sourcesContent":["import type { TargetHasher } from \"@lage-run/hasher\";\nimport type { Logger } from \"@lage-run/logger\";\nimport { type LogEntry, LogLevel } from \"@lage-run/logger\";\nimport type { TargetRun, TargetStatus } from \"@lage-run/scheduler-types\";\nimport { getStartTargetId, type Target } from \"@lage-run/target-graph\";\nimport type { Pool } from \"@lage-run/worker-threads-pool\";\nimport fs from \"fs\";\nimport { mkdir, writeFile } from \"fs/promises\";\nimport path from \"path\";\nimport type { MessagePort } from \"worker_threads\";\nimport { bufferTransform } from \"./bufferTransform.js\";\nimport { getLageOutputCacheLocation } from \"./getLageOutputCacheLocation.js\";\n\nexport interface WrappedTargetOptions {\n root: string;\n target: Target;\n logger: Logger;\n shouldCache: boolean;\n continueOnError: boolean;\n abortController: AbortController;\n pool: Pool;\n hasher: TargetHasher;\n onMessage?: (message: any, postMessage: MessagePort[\"postMessage\"]) => void;\n}\n\nexport interface WorkerResult {\n stdoutBuffer: string;\n stderrBuffer: string;\n skipped: boolean;\n hash: string;\n value: unknown;\n id: string;\n}\n\n/**\n * Wraps a target with additional functionality:\n * 1. Caching\n * 2. Logging\n * 3. Abort signal\n * 4. Continue on error\n */\nexport class WrappedTarget implements TargetRun<WorkerResult> {\n #status: TargetStatus = \"pending\";\n #result: WorkerResult | undefined;\n public queueTime: [number, number] = [0, 0];\n public startTime: [number, number] = [0, 0];\n public duration: [number, number] = [0, 0];\n public target: Target;\n public threadId = 0;\n\n public get result(): WorkerResult | undefined {\n return this.#result;\n }\n\n public get status(): TargetStatus {\n return this.#status;\n }\n\n public get successful(): boolean {\n return this.#status === \"skipped\" || this.#status === \"success\";\n }\n\n public get waiting(): boolean {\n return this.#status === \"pending\" || this.#status === \"queued\";\n }\n\n constructor(public options: WrappedTargetOptions) {\n this.target = options.target;\n\n if (this.target.id === getStartTargetId()) {\n this.#status = \"success\";\n }\n\n this.options.logger.info(\"\", { target: this.target, status: this.status });\n }\n\n public onQueued(): void {\n this.#status = \"queued\";\n this.queueTime = process.hrtime();\n this.options.logger.info(\"\", { target: this.target, status: \"queued\" });\n }\n\n private onAbort(): void {\n this.#status = \"aborted\";\n this.options.logger.info(\"\", { target: this.target, status: \"aborted\", threadId: this.threadId });\n }\n\n private onStart(threadId: number): void {\n if (this.status !== \"running\") {\n this.threadId = threadId;\n this.#status = \"running\";\n this.startTime = process.hrtime();\n this.options.logger.info(\"\", { target: this.target, status: \"running\", threadId });\n }\n }\n\n private onComplete(): void {\n this.#status = \"success\";\n this.options.logger.info(\"\", {\n target: this.target,\n status: \"success\",\n duration: this.duration,\n threadId: this.threadId,\n });\n }\n\n private onFail(): void {\n this.#status = \"failed\";\n this.options.logger.info(\"\", {\n target: this.target,\n status: \"failed\",\n duration: this.duration,\n threadId: this.threadId,\n });\n\n if (!this.options.continueOnError && this.options.abortController) {\n this.options.abortController.abort();\n }\n }\n\n public onSkipped(hash?: string | undefined): void {\n this.#status = \"skipped\";\n\n if (hash) {\n this.options.logger.info(\"\", {\n target: this.target,\n status: \"skipped\",\n duration: this.duration,\n hash,\n threadId: this.threadId,\n });\n }\n }\n\n public async run(): Promise<WorkerResult | undefined> {\n const { target, logger, shouldCache, abortController, root } = this.options;\n\n const abortSignal = abortController.signal;\n\n if (abortSignal.aborted) {\n this.onStart(0);\n this.onAbort();\n return;\n }\n\n try {\n this.#result = await this.runInPool();\n\n const cacheEnabled = target.cache && shouldCache && this.#result.hash;\n // Save output if cache is enabled & cache is hit\n if (!this.#result.skipped && cacheEnabled) {\n const outputLocation = getLageOutputCacheLocation(root, this.#result.hash);\n const outputPath = path.dirname(outputLocation);\n await mkdir(outputPath, { recursive: true });\n\n const output = `${this.#result.stdoutBuffer}\\n${this.#result.stderrBuffer}`;\n\n await writeFile(outputLocation, output);\n\n logger.verbose(`>> Saved cache - ${this.#result.hash}`, { target });\n }\n\n if (this.#result.skipped) {\n const { hash } = this.#result;\n\n const cachedOutputFile = getLageOutputCacheLocation(root, hash ?? \"\");\n\n const shouldShowCachedOutput = fs.existsSync(cachedOutputFile);\n if (shouldShowCachedOutput) {\n const cachedOutput = fs.readFileSync(cachedOutputFile, \"utf8\");\n logger.verbose(\">> Replaying cached output\", { target });\n logger.verbose(cachedOutput.trim(), { target });\n }\n\n this.onSkipped(hash);\n } else {\n this.onComplete();\n }\n\n return this.#result;\n } catch (e) {\n if (e instanceof Error) {\n logger.error(String(e), { target });\n }\n\n if (abortSignal.aborted) {\n this.onAbort();\n } else {\n this.onFail();\n }\n\n throw e;\n }\n }\n\n private async runInPool(): Promise<WorkerResult> {\n const { target, logger, abortController, pool } = this.options;\n const abortSignal = abortController.signal;\n\n let releaseStdout: any;\n let releaseStderr: any;\n\n const bufferStdout = bufferTransform();\n const bufferStderr = bufferTransform();\n\n let msgHandler: (data: LogEntry<any> & { type: string }) => void;\n\n const result = await (pool.exec(\n { target },\n target.weight ?? 1,\n (worker, stdout, stderr) => {\n const postMessage = worker.postMessage.bind(worker);\n\n msgHandler = (data) => {\n if (data.type === \"log\") {\n logger.log(data.level, data.msg, { target, threadId: worker.threadId });\n } else if (data.type === \"hash\") {\n void this.options.hasher\n .hash(target)\n .then((hash) => {\n worker.postMessage({ type: \"hash\", hash });\n })\n .catch((e) => {\n logger.warn(`Failed to hash target ${target.id}: ${e instanceof Error ? e.message : String(e)}`);\n });\n } else if (this.options.onMessage) {\n this.options.onMessage(data, postMessage);\n }\n };\n\n worker.on(\"message\", msgHandler);\n\n const threadId = worker.threadId;\n\n this.onStart(threadId);\n\n stdout.pipe(bufferStdout.transform);\n stderr.pipe(bufferStderr.transform);\n\n const releaseStdoutStream = logger.stream(LogLevel.verbose, stdout, { target, threadId });\n\n releaseStdout = () => {\n releaseStdoutStream();\n stdout.unpipe(bufferStdout.transform);\n };\n\n const releaseStderrStream = logger.stream(LogLevel.verbose, stderr, { target, threadId });\n\n releaseStderr = () => {\n releaseStderrStream();\n stderr.unpipe(bufferStderr.transform);\n };\n },\n (worker) => {\n worker.off(\"message\", msgHandler);\n this.duration = process.hrtime(this.startTime);\n releaseStdout();\n releaseStderr();\n },\n abortSignal,\n target.priority\n ) as Promise<{ value?: unknown; skipped: boolean; hash: string; id: string }>);\n\n return {\n stdoutBuffer: bufferStdout.buffer,\n stderrBuffer: bufferStderr.buffer,\n skipped: result?.skipped,\n hash: result?.hash,\n value: result?.value,\n id: result?.id,\n };\n }\n\n /**\n * A JSON representation of this wrapped target, used in Jest snapshots.\n *\n * Skips the unpredictable properties of the wrapped target like the startTime and duration.\n */\n public toJSON(): {\n target: string;\n status: TargetStatus;\n } {\n return {\n target: this.target.id,\n status: this.status,\n };\n }\n\n /**\n * Reset the state of this wrapped target.\n */\n public reset(): void {\n this.#result = undefined;\n this.#status = \"pending\";\n }\n}\n"],"names":["WrappedTarget","result","status","successful","waiting","onQueued","queueTime","process","hrtime","options","logger","info","target","onAbort","threadId","onStart","startTime","onComplete","duration","onFail","continueOnError","abortController","abort","onSkipped","hash","run","shouldCache","root","abortSignal","signal","aborted","runInPool","cacheEnabled","cache","skipped","outputLocation","getLageOutputCacheLocation","outputPath","path","dirname","mkdir","recursive","output","stdoutBuffer","stderrBuffer","writeFile","verbose","cachedOutputFile","shouldShowCachedOutput","fs","existsSync","cachedOutput","readFileSync","trim","e","Error","error","String","pool","releaseStdout","releaseStderr","bufferStdout","bufferTransform","bufferStderr","msgHandler","exec","weight","worker","stdout","stderr","postMessage","bind","data","type","log","level","msg","hasher","then","catch","warn","id","message","onMessage","on","pipe","transform","releaseStdoutStream","stream","LogLevel","unpipe","releaseStderrStream","off","priority","buffer","value","toJSON","reset","undefined","getStartTargetId"],"mappings":"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"}
@@ -8,7 +8,7 @@ interface CreateCacheOptions {
8
8
  skipLocalCache: boolean;
9
9
  cliArgs: string[];
10
10
  }
11
- export declare function createCache(options: CreateCacheOptions): Promise<{
11
+ export declare function createCache(options: CreateCacheOptions): {
12
12
  cacheProvider: RemoteFallbackCacheProvider;
13
- }>;
13
+ };
14
14
  export {};
@@ -9,8 +9,8 @@ Object.defineProperty(exports, "createCache", {
9
9
  }
10
10
  });
11
11
  const _cache = require("@lage-run/cache");
12
- const _isRunningFromCI = require("./isRunningFromCI.js");
13
- async function createCache(options) {
12
+ const _config = require("@lage-run/config");
13
+ function createCache(options) {
14
14
  const { cacheOptions, logger, root, skipLocalCache } = options;
15
15
  const hasRemoteCacheConfig = !!cacheOptions?.cacheStorageConfig || !!process.env.BACKFILL_CACHE_PROVIDER || !!process.env.BACKFILL_CACHE_PROVIDER_OPTIONS;
16
16
  // Create Cache Provider
@@ -35,7 +35,7 @@ async function createCache(options) {
35
35
  root,
36
36
  cacheOptions: cacheOptions ?? {}
37
37
  }) : undefined,
38
- writeRemoteCache: (cacheOptions?.writeRemoteCache === true || String(process.env.LAGE_WRITE_CACHE).toLowerCase() === "true" || _isRunningFromCI.isRunningFromCI) && String(process.env.LAGE_WRITE_CACHE).toLowerCase() !== "false"
38
+ writeRemoteCache: (cacheOptions?.writeRemoteCache === true || String(process.env.LAGE_WRITE_CACHE).toLowerCase() === "true" || _config.isRunningFromCI) && String(process.env.LAGE_WRITE_CACHE).toLowerCase() !== "false"
39
39
  });
40
40
  return {
41
41
  cacheProvider
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cache/createCacheProvider.ts"],"sourcesContent":["import type { CacheOptions } from \"@lage-run/cache\";\nimport { BackfillCacheProvider, RemoteFallbackCacheProvider } from \"@lage-run/cache\";\nimport type { Logger } from \"@lage-run/logger\";\nimport { isRunningFromCI } from \"./isRunningFromCI.js\";\n\ninterface CreateCacheOptions {\n cacheOptions?: CacheOptions;\n logger: Logger;\n root: string;\n skipLocalCache: boolean;\n cliArgs: string[];\n}\n\nexport async function createCache(options: CreateCacheOptions): Promise<{\n cacheProvider: RemoteFallbackCacheProvider;\n}> {\n const { cacheOptions, logger, root, skipLocalCache } = options;\n\n const hasRemoteCacheConfig =\n !!cacheOptions?.cacheStorageConfig || !!process.env.BACKFILL_CACHE_PROVIDER || !!process.env.BACKFILL_CACHE_PROVIDER_OPTIONS;\n\n // Create Cache Provider\n const cacheProvider = new RemoteFallbackCacheProvider({\n root,\n logger,\n localCacheProvider:\n skipLocalCache === true\n ? undefined\n : new BackfillCacheProvider({\n logger,\n root,\n cacheOptions: {\n outputGlob: cacheOptions?.outputGlob,\n ...(cacheOptions?.internalCacheFolder && { internalCacheFolder: cacheOptions.internalCacheFolder }),\n ...(cacheOptions?.incrementalCaching && { incrementalCaching: cacheOptions.incrementalCaching }),\n },\n }),\n remoteCacheProvider: hasRemoteCacheConfig ? new BackfillCacheProvider({ logger, root, cacheOptions: cacheOptions ?? {} }) : undefined,\n writeRemoteCache:\n (cacheOptions?.writeRemoteCache === true || String(process.env.LAGE_WRITE_CACHE).toLowerCase() === \"true\" || isRunningFromCI) &&\n String(process.env.LAGE_WRITE_CACHE).toLowerCase() !== \"false\",\n });\n\n return { cacheProvider };\n}\n"],"names":["createCache","options","cacheOptions","logger","root","skipLocalCache","hasRemoteCacheConfig","cacheStorageConfig","process","env","BACKFILL_CACHE_PROVIDER","BACKFILL_CACHE_PROVIDER_OPTIONS","cacheProvider","RemoteFallbackCacheProvider","localCacheProvider","undefined","BackfillCacheProvider","outputGlob","internalCacheFolder","incrementalCaching","remoteCacheProvider","writeRemoteCache","String","LAGE_WRITE_CACHE","toLowerCase","isRunningFromCI"],"mappings":";;;;+BAasBA;;;eAAAA;;;uBAZ6C;iCAEnC;AAUzB,eAAeA,YAAYC,OAA2B;IAG3D,MAAM,EAAEC,YAAY,EAAEC,MAAM,EAAEC,IAAI,EAAEC,cAAc,EAAE,GAAGJ;IAEvD,MAAMK,uBACJ,CAAC,CAACJ,cAAcK,sBAAsB,CAAC,CAACC,QAAQC,GAAG,CAACC,uBAAuB,IAAI,CAAC,CAACF,QAAQC,GAAG,CAACE,+BAA+B;IAE9H,wBAAwB;IACxB,MAAMC,gBAAgB,IAAIC,kCAA2B,CAAC;QACpDT;QACAD;QACAW,oBACET,mBAAmB,OACfU,YACA,IAAIC,4BAAqB,CAAC;YACxBb;YACAC;YACAF,cAAc;gBACZe,YAAYf,cAAce;gBAC1B,GAAIf,cAAcgB,uBAAuB;oBAAEA,qBAAqBhB,aAAagB,mBAAmB;gBAAC,CAAC;gBAClG,GAAIhB,cAAciB,sBAAsB;oBAAEA,oBAAoBjB,aAAaiB,kBAAkB;gBAAC,CAAC;YACjG;QACF;QACNC,qBAAqBd,uBAAuB,IAAIU,4BAAqB,CAAC;YAAEb;YAAQC;YAAMF,cAAcA,gBAAgB,CAAC;QAAE,KAAKa;QAC5HM,kBACE,AAACnB,CAAAA,cAAcmB,qBAAqB,QAAQC,OAAOd,QAAQC,GAAG,CAACc,gBAAgB,EAAEC,WAAW,OAAO,UAAUC,gCAAe,AAAD,KAC3HH,OAAOd,QAAQC,GAAG,CAACc,gBAAgB,EAAEC,WAAW,OAAO;IAC3D;IAEA,OAAO;QAAEZ;IAAc;AACzB"}
1
+ {"version":3,"sources":["../../src/cache/createCacheProvider.ts"],"sourcesContent":["import type { CacheOptions } from \"@lage-run/cache\";\nimport { BackfillCacheProvider, RemoteFallbackCacheProvider } from \"@lage-run/cache\";\nimport { isRunningFromCI } from \"@lage-run/config\";\nimport type { Logger } from \"@lage-run/logger\";\n\ninterface CreateCacheOptions {\n cacheOptions?: CacheOptions;\n logger: Logger;\n root: string;\n skipLocalCache: boolean;\n cliArgs: string[];\n}\n\nexport function createCache(options: CreateCacheOptions): {\n cacheProvider: RemoteFallbackCacheProvider;\n} {\n const { cacheOptions, logger, root, skipLocalCache } = options;\n\n const hasRemoteCacheConfig =\n !!cacheOptions?.cacheStorageConfig || !!process.env.BACKFILL_CACHE_PROVIDER || !!process.env.BACKFILL_CACHE_PROVIDER_OPTIONS;\n\n // Create Cache Provider\n const cacheProvider = new RemoteFallbackCacheProvider({\n root,\n logger,\n localCacheProvider:\n skipLocalCache === true\n ? undefined\n : new BackfillCacheProvider({\n logger,\n root,\n cacheOptions: {\n outputGlob: cacheOptions?.outputGlob,\n ...(cacheOptions?.internalCacheFolder && { internalCacheFolder: cacheOptions.internalCacheFolder }),\n ...(cacheOptions?.incrementalCaching && { incrementalCaching: cacheOptions.incrementalCaching }),\n },\n }),\n remoteCacheProvider: hasRemoteCacheConfig ? new BackfillCacheProvider({ logger, root, cacheOptions: cacheOptions ?? {} }) : undefined,\n writeRemoteCache:\n (cacheOptions?.writeRemoteCache === true || String(process.env.LAGE_WRITE_CACHE).toLowerCase() === \"true\" || isRunningFromCI) &&\n String(process.env.LAGE_WRITE_CACHE).toLowerCase() !== \"false\",\n });\n\n return { cacheProvider };\n}\n"],"names":["createCache","options","cacheOptions","logger","root","skipLocalCache","hasRemoteCacheConfig","cacheStorageConfig","process","env","BACKFILL_CACHE_PROVIDER","BACKFILL_CACHE_PROVIDER_OPTIONS","cacheProvider","RemoteFallbackCacheProvider","localCacheProvider","undefined","BackfillCacheProvider","outputGlob","internalCacheFolder","incrementalCaching","remoteCacheProvider","writeRemoteCache","String","LAGE_WRITE_CACHE","toLowerCase","isRunningFromCI"],"mappings":";;;;+BAagBA;;;eAAAA;;;uBAZmD;wBACnC;AAWzB,SAASA,YAAYC,OAA2B;IAGrD,MAAM,EAAEC,YAAY,EAAEC,MAAM,EAAEC,IAAI,EAAEC,cAAc,EAAE,GAAGJ;IAEvD,MAAMK,uBACJ,CAAC,CAACJ,cAAcK,sBAAsB,CAAC,CAACC,QAAQC,GAAG,CAACC,uBAAuB,IAAI,CAAC,CAACF,QAAQC,GAAG,CAACE,+BAA+B;IAE9H,wBAAwB;IACxB,MAAMC,gBAAgB,IAAIC,kCAA2B,CAAC;QACpDT;QACAD;QACAW,oBACET,mBAAmB,OACfU,YACA,IAAIC,4BAAqB,CAAC;YACxBb;YACAC;YACAF,cAAc;gBACZe,YAAYf,cAAce;gBAC1B,GAAIf,cAAcgB,uBAAuB;oBAAEA,qBAAqBhB,aAAagB,mBAAmB;gBAAC,CAAC;gBAClG,GAAIhB,cAAciB,sBAAsB;oBAAEA,oBAAoBjB,aAAaiB,kBAAkB;gBAAC,CAAC;YACjG;QACF;QACNC,qBAAqBd,uBAAuB,IAAIU,4BAAqB,CAAC;YAAEb;YAAQC;YAAMF,cAAcA,gBAAgB,CAAC;QAAE,KAAKa;QAC5HM,kBACE,AAACnB,CAAAA,cAAcmB,qBAAqB,QAAQC,OAAOd,QAAQC,GAAG,CAACc,gBAAgB,EAAEC,WAAW,OAAO,UAAUC,uBAAe,AAAD,KAC3HH,OAAOd,QAAQC,GAAG,CAACc,gBAAgB,EAAEC,WAAW,OAAO;IAC3D;IAEA,OAAO;QAAEZ;IAAc;AACzB"}
@@ -12,7 +12,7 @@ function _interop_require_default(obj) {
12
12
  default: obj
13
13
  };
14
14
  }
15
- async function setup(options) {
15
+ function setup(options) {
16
16
  const { runners, root, cacheOptions } = options;
17
17
  const logger = (0, _logger.default)();
18
18
  logger.addReporter({
@@ -24,7 +24,7 @@ async function setup(options) {
24
24
  },
25
25
  summarize () {}
26
26
  });
27
- const { cacheProvider } = await (0, _createCacheProvider.createCache)({
27
+ const { cacheProvider } = (0, _createCacheProvider.createCache)({
28
28
  root,
29
29
  logger,
30
30
  cacheOptions,
@@ -38,64 +38,62 @@ async function setup(options) {
38
38
  cacheProvider
39
39
  };
40
40
  }
41
- void (async ()=>{
42
- const { cacheProvider, runnerPicker, options } = await setup(_worker_threads.workerData);
43
- let hashPromiseResolve = (_hash)=>{};
44
- // main thread sends hash to worker because it keeps a global memory cache of the hashes
45
- _worker_threads.parentPort.on("message", (data)=>{
46
- if (data.type === "hash") {
47
- hashPromiseResolve(data.hash);
48
- }
49
- });
50
- async function getCache(target) {
51
- const { shouldCache, shouldResetCache } = options;
52
- let hash = undefined;
53
- let cacheHit = false;
54
- if (!shouldCache || !target.cache || !cacheProvider) {
55
- return {
56
- hash,
57
- cacheHit
58
- };
59
- }
60
- // using a special pattern in communicating with the main thread to get the hash for the target
61
- hash = await new Promise((resolve)=>{
62
- hashPromiseResolve = resolve;
63
- _worker_threads.parentPort.postMessage({
64
- type: "hash"
65
- });
66
- });
67
- if (hash && !shouldResetCache) {
68
- cacheHit = await cacheProvider.fetch(hash, target);
69
- }
41
+ const { cacheProvider, runnerPicker, options } = setup(_worker_threads.workerData);
42
+ let hashPromiseResolve = (_hash)=>{};
43
+ // main thread sends hash to worker because it keeps a global memory cache of the hashes
44
+ _worker_threads.parentPort.on("message", (data)=>{
45
+ if (data.type === "hash") {
46
+ hashPromiseResolve(data.hash);
47
+ }
48
+ });
49
+ async function getCache(target) {
50
+ const { shouldCache, shouldResetCache } = options;
51
+ let hash = undefined;
52
+ let cacheHit = false;
53
+ if (!shouldCache || !target.cache || !cacheProvider) {
70
54
  return {
71
55
  hash,
72
56
  cacheHit
73
57
  };
74
58
  }
75
- async function saveCache(target, hash) {
76
- if (!hash || !cacheProvider) {
77
- return;
78
- }
79
- await cacheProvider.put(hash, target);
59
+ // using a special pattern in communicating with the main thread to get the hash for the target
60
+ hash = await new Promise((resolve)=>{
61
+ hashPromiseResolve = resolve;
62
+ _worker_threads.parentPort.postMessage({
63
+ type: "hash"
64
+ });
65
+ });
66
+ if (hash && !shouldResetCache) {
67
+ cacheHit = await cacheProvider.fetch(hash, target);
80
68
  }
81
- async function run(data, abortSignal) {
82
- const { hash, cacheHit } = await getCache(data.target);
83
- const cacheEnabled = data.target.cache && options.shouldCache && hash;
84
- let value = undefined;
85
- if (!cacheHit || !cacheEnabled) {
86
- const runner = await runnerPicker.pick(data.target);
87
- value = await runner.run({
88
- ...data,
89
- abortSignal
90
- });
91
- await saveCache(data.target, hash);
92
- }
93
- return {
94
- skipped: cacheHit,
95
- id: data.target.id,
96
- hash,
97
- value
98
- };
69
+ return {
70
+ hash,
71
+ cacheHit
72
+ };
73
+ }
74
+ async function saveCache(target, hash) {
75
+ if (!hash || !cacheProvider) {
76
+ return;
77
+ }
78
+ await cacheProvider.put(hash, target);
79
+ }
80
+ async function run(data, abortSignal) {
81
+ const { hash, cacheHit } = await getCache(data.target);
82
+ const cacheEnabled = data.target.cache && options.shouldCache && hash;
83
+ let value = undefined;
84
+ if (!cacheHit || !cacheEnabled) {
85
+ const runner = await runnerPicker.pick(data.target);
86
+ value = await runner.run({
87
+ ...data,
88
+ abortSignal
89
+ });
90
+ await saveCache(data.target, hash);
99
91
  }
100
- (0, _workerthreadspool.registerWorker)(run);
101
- })();
92
+ return {
93
+ skipped: cacheHit,
94
+ id: data.target.id,
95
+ hash,
96
+ value
97
+ };
98
+ }
99
+ (0, _workerthreadspool.registerWorker)(run);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/workers/targetWorker.ts"],"sourcesContent":["import { createCache } from \"../cache/createCacheProvider.js\";\nimport { registerWorker } from \"@lage-run/worker-threads-pool\";\nimport { TargetRunnerPicker } from \"@lage-run/runners\";\nimport { parentPort, workerData } from \"worker_threads\";\nimport createLogger from \"@lage-run/logger\";\n\nimport type { CacheOptions } from \"@lage-run/config\";\nimport type { Target } from \"@lage-run/target-graph\";\nimport type { TargetRunnerPickerOptions } from \"@lage-run/runners\";\n\ninterface TargetWorkerDataOptions {\n runners: TargetRunnerPickerOptions;\n skipLocalCache: boolean;\n shouldCache: boolean;\n shouldResetCache: boolean;\n taskArgs: string[];\n root: string;\n cacheOptions?: CacheOptions;\n}\n\nasync function setup(options: TargetWorkerDataOptions) {\n const { runners, root, cacheOptions } = options;\n\n const logger = createLogger();\n logger.addReporter({\n log(entry) {\n parentPort!.postMessage({ type: \"log\", ...entry });\n },\n summarize() {},\n });\n\n const { cacheProvider } = await createCache({\n root,\n logger,\n cacheOptions,\n cliArgs: options.taskArgs,\n skipLocalCache: options.skipLocalCache,\n });\n\n const runnerPicker = new TargetRunnerPicker(runners);\n\n return {\n options,\n runnerPicker,\n cacheProvider,\n };\n}\n\nvoid (async () => {\n const { cacheProvider, runnerPicker, options } = await setup(workerData);\n\n let hashPromiseResolve = (_hash: string) => {};\n\n // main thread sends hash to worker because it keeps a global memory cache of the hashes\n parentPort!.on(\"message\", (data: any) => {\n if (data.type === \"hash\") {\n hashPromiseResolve(data.hash);\n }\n });\n\n async function getCache(target: Target) {\n const { shouldCache, shouldResetCache } = options;\n let hash: string | undefined = undefined;\n let cacheHit = false;\n\n if (!shouldCache || !target.cache || !cacheProvider) {\n return { hash, cacheHit };\n }\n\n // using a special pattern in communicating with the main thread to get the hash for the target\n hash = await new Promise((resolve) => {\n hashPromiseResolve = resolve;\n parentPort!.postMessage({ type: \"hash\" });\n });\n\n if (hash && !shouldResetCache) {\n cacheHit = await cacheProvider.fetch(hash, target);\n }\n\n return { hash, cacheHit };\n }\n\n async function saveCache(target: Target, hash: string | undefined) {\n if (!hash || !cacheProvider) {\n return;\n }\n await cacheProvider.put(hash, target);\n }\n\n async function run(data: any, abortSignal?: AbortSignal) {\n const { hash, cacheHit } = await getCache(data.target);\n\n const cacheEnabled = data.target.cache && options.shouldCache && hash;\n\n let value: unknown = undefined;\n if (!cacheHit || !cacheEnabled) {\n const runner = await runnerPicker.pick(data.target);\n value = await runner.run({\n ...data,\n abortSignal,\n });\n\n await saveCache(data.target, hash);\n }\n\n return {\n skipped: cacheHit,\n id: data.target.id,\n hash,\n value,\n };\n }\n\n registerWorker(run);\n})();\n"],"names":["setup","options","runners","root","cacheOptions","logger","createLogger","addReporter","log","entry","parentPort","postMessage","type","summarize","cacheProvider","createCache","cliArgs","taskArgs","skipLocalCache","runnerPicker","TargetRunnerPicker","workerData","hashPromiseResolve","_hash","on","data","hash","getCache","target","shouldCache","shouldResetCache","undefined","cacheHit","cache","Promise","resolve","fetch","saveCache","put","run","abortSignal","cacheEnabled","value","runner","pick","skipped","id","registerWorker"],"mappings":";;;;qCAA4B;mCACG;yBACI;gCACI;+DACd;;;;;;AAgBzB,eAAeA,MAAMC,OAAgC;IACnD,MAAM,EAAEC,OAAO,EAAEC,IAAI,EAAEC,YAAY,EAAE,GAAGH;IAExC,MAAMI,SAASC,IAAAA,eAAY;IAC3BD,OAAOE,WAAW,CAAC;QACjBC,KAAIC,KAAK;YACPC,0BAAU,CAAEC,WAAW,CAAC;gBAAEC,MAAM;gBAAO,GAAGH,KAAK;YAAC;QAClD;QACAI,cAAa;IACf;IAEA,MAAM,EAAEC,aAAa,EAAE,GAAG,MAAMC,IAAAA,gCAAW,EAAC;QAC1CZ;QACAE;QACAD;QACAY,SAASf,QAAQgB,QAAQ;QACzBC,gBAAgBjB,QAAQiB,cAAc;IACxC;IAEA,MAAMC,eAAe,IAAIC,2BAAkB,CAAClB;IAE5C,OAAO;QACLD;QACAkB;QACAL;IACF;AACF;AAEA,KAAK,AAAC,CAAA;IACJ,MAAM,EAAEA,aAAa,EAAEK,YAAY,EAAElB,OAAO,EAAE,GAAG,MAAMD,MAAMqB,0BAAU;IAEvE,IAAIC,qBAAqB,CAACC,SAAmB;IAE7C,wFAAwF;IACxFb,0BAAU,CAAEc,EAAE,CAAC,WAAW,CAACC;QACzB,IAAIA,KAAKb,IAAI,KAAK,QAAQ;YACxBU,mBAAmBG,KAAKC,IAAI;QAC9B;IACF;IAEA,eAAeC,SAASC,MAAc;QACpC,MAAM,EAAEC,WAAW,EAAEC,gBAAgB,EAAE,GAAG7B;QAC1C,IAAIyB,OAA2BK;QAC/B,IAAIC,WAAW;QAEf,IAAI,CAACH,eAAe,CAACD,OAAOK,KAAK,IAAI,CAACnB,eAAe;YACnD,OAAO;gBAAEY;gBAAMM;YAAS;QAC1B;QAEA,+FAA+F;QAC/FN,OAAO,MAAM,IAAIQ,QAAQ,CAACC;YACxBb,qBAAqBa;YACrBzB,0BAAU,CAAEC,WAAW,CAAC;gBAAEC,MAAM;YAAO;QACzC;QAEA,IAAIc,QAAQ,CAACI,kBAAkB;YAC7BE,WAAW,MAAMlB,cAAcsB,KAAK,CAACV,MAAME;QAC7C;QAEA,OAAO;YAAEF;YAAMM;QAAS;IAC1B;IAEA,eAAeK,UAAUT,MAAc,EAAEF,IAAwB;QAC/D,IAAI,CAACA,QAAQ,CAACZ,eAAe;YAC3B;QACF;QACA,MAAMA,cAAcwB,GAAG,CAACZ,MAAME;IAChC;IAEA,eAAeW,IAAId,IAAS,EAAEe,WAAyB;QACrD,MAAM,EAAEd,IAAI,EAAEM,QAAQ,EAAE,GAAG,MAAML,SAASF,KAAKG,MAAM;QAErD,MAAMa,eAAehB,KAAKG,MAAM,CAACK,KAAK,IAAIhC,QAAQ4B,WAAW,IAAIH;QAEjE,IAAIgB,QAAiBX;QACrB,IAAI,CAACC,YAAY,CAACS,cAAc;YAC9B,MAAME,SAAS,MAAMxB,aAAayB,IAAI,CAACnB,KAAKG,MAAM;YAClDc,QAAQ,MAAMC,OAAOJ,GAAG,CAAC;gBACvB,GAAGd,IAAI;gBACPe;YACF;YAEA,MAAMH,UAAUZ,KAAKG,MAAM,EAAEF;QAC/B;QAEA,OAAO;YACLmB,SAASb;YACTc,IAAIrB,KAAKG,MAAM,CAACkB,EAAE;YAClBpB;YACAgB;QACF;IACF;IAEAK,IAAAA,iCAAc,EAACR;AACjB,CAAA"}
1
+ {"version":3,"sources":["../../src/workers/targetWorker.ts"],"sourcesContent":["import { createCache } from \"../cache/createCacheProvider.js\";\nimport { registerWorker } from \"@lage-run/worker-threads-pool\";\nimport { TargetRunnerPicker } from \"@lage-run/runners\";\nimport { parentPort, workerData } from \"worker_threads\";\nimport createLogger from \"@lage-run/logger\";\n\nimport type { CacheOptions } from \"@lage-run/config\";\nimport type { Target } from \"@lage-run/target-graph\";\nimport type { TargetRunnerPickerOptions } from \"@lage-run/runners\";\n\ninterface TargetWorkerDataOptions {\n runners: TargetRunnerPickerOptions;\n skipLocalCache: boolean;\n shouldCache: boolean;\n shouldResetCache: boolean;\n taskArgs: string[];\n root: string;\n cacheOptions?: CacheOptions;\n}\n\nfunction setup(options: TargetWorkerDataOptions) {\n const { runners, root, cacheOptions } = options;\n\n const logger = createLogger();\n logger.addReporter({\n log(entry) {\n parentPort!.postMessage({ type: \"log\", ...entry });\n },\n summarize() {},\n });\n\n const { cacheProvider } = createCache({\n root,\n logger,\n cacheOptions,\n cliArgs: options.taskArgs,\n skipLocalCache: options.skipLocalCache,\n });\n\n const runnerPicker = new TargetRunnerPicker(runners);\n\n return {\n options,\n runnerPicker,\n cacheProvider,\n };\n}\n\nconst { cacheProvider, runnerPicker, options } = setup(workerData);\n\nlet hashPromiseResolve = (_hash: string) => {};\n\n// main thread sends hash to worker because it keeps a global memory cache of the hashes\nparentPort!.on(\"message\", (data: any) => {\n if (data.type === \"hash\") {\n hashPromiseResolve(data.hash);\n }\n});\n\nasync function getCache(target: Target) {\n const { shouldCache, shouldResetCache } = options;\n let hash: string | undefined = undefined;\n let cacheHit = false;\n\n if (!shouldCache || !target.cache || !cacheProvider) {\n return { hash, cacheHit };\n }\n\n // using a special pattern in communicating with the main thread to get the hash for the target\n hash = await new Promise((resolve) => {\n hashPromiseResolve = resolve;\n parentPort!.postMessage({ type: \"hash\" });\n });\n\n if (hash && !shouldResetCache) {\n cacheHit = await cacheProvider.fetch(hash, target);\n }\n\n return { hash, cacheHit };\n}\n\nasync function saveCache(target: Target, hash: string | undefined) {\n if (!hash || !cacheProvider) {\n return;\n }\n await cacheProvider.put(hash, target);\n}\n\nasync function run(data: any, abortSignal?: AbortSignal) {\n const { hash, cacheHit } = await getCache(data.target);\n\n const cacheEnabled = data.target.cache && options.shouldCache && hash;\n\n let value: unknown = undefined;\n if (!cacheHit || !cacheEnabled) {\n const runner = await runnerPicker.pick(data.target);\n value = await runner.run({\n ...data,\n abortSignal,\n });\n\n await saveCache(data.target, hash);\n }\n\n return {\n skipped: cacheHit,\n id: data.target.id,\n hash,\n value,\n };\n}\n\nregisterWorker(run);\n"],"names":["setup","options","runners","root","cacheOptions","logger","createLogger","addReporter","log","entry","parentPort","postMessage","type","summarize","cacheProvider","createCache","cliArgs","taskArgs","skipLocalCache","runnerPicker","TargetRunnerPicker","workerData","hashPromiseResolve","_hash","on","data","hash","getCache","target","shouldCache","shouldResetCache","undefined","cacheHit","cache","Promise","resolve","fetch","saveCache","put","run","abortSignal","cacheEnabled","value","runner","pick","skipped","id","registerWorker"],"mappings":";;;;qCAA4B;mCACG;yBACI;gCACI;+DACd;;;;;;AAgBzB,SAASA,MAAMC,OAAgC;IAC7C,MAAM,EAAEC,OAAO,EAAEC,IAAI,EAAEC,YAAY,EAAE,GAAGH;IAExC,MAAMI,SAASC,IAAAA,eAAY;IAC3BD,OAAOE,WAAW,CAAC;QACjBC,KAAIC,KAAK;YACPC,0BAAU,CAAEC,WAAW,CAAC;gBAAEC,MAAM;gBAAO,GAAGH,KAAK;YAAC;QAClD;QACAI,cAAa;IACf;IAEA,MAAM,EAAEC,aAAa,EAAE,GAAGC,IAAAA,gCAAW,EAAC;QACpCZ;QACAE;QACAD;QACAY,SAASf,QAAQgB,QAAQ;QACzBC,gBAAgBjB,QAAQiB,cAAc;IACxC;IAEA,MAAMC,eAAe,IAAIC,2BAAkB,CAAClB;IAE5C,OAAO;QACLD;QACAkB;QACAL;IACF;AACF;AAEA,MAAM,EAAEA,aAAa,EAAEK,YAAY,EAAElB,OAAO,EAAE,GAAGD,MAAMqB,0BAAU;AAEjE,IAAIC,qBAAqB,CAACC,SAAmB;AAE7C,wFAAwF;AACxFb,0BAAU,CAAEc,EAAE,CAAC,WAAW,CAACC;IACzB,IAAIA,KAAKb,IAAI,KAAK,QAAQ;QACxBU,mBAAmBG,KAAKC,IAAI;IAC9B;AACF;AAEA,eAAeC,SAASC,MAAc;IACpC,MAAM,EAAEC,WAAW,EAAEC,gBAAgB,EAAE,GAAG7B;IAC1C,IAAIyB,OAA2BK;IAC/B,IAAIC,WAAW;IAEf,IAAI,CAACH,eAAe,CAACD,OAAOK,KAAK,IAAI,CAACnB,eAAe;QACnD,OAAO;YAAEY;YAAMM;QAAS;IAC1B;IAEA,+FAA+F;IAC/FN,OAAO,MAAM,IAAIQ,QAAQ,CAACC;QACxBb,qBAAqBa;QACrBzB,0BAAU,CAAEC,WAAW,CAAC;YAAEC,MAAM;QAAO;IACzC;IAEA,IAAIc,QAAQ,CAACI,kBAAkB;QAC7BE,WAAW,MAAMlB,cAAcsB,KAAK,CAACV,MAAME;IAC7C;IAEA,OAAO;QAAEF;QAAMM;IAAS;AAC1B;AAEA,eAAeK,UAAUT,MAAc,EAAEF,IAAwB;IAC/D,IAAI,CAACA,QAAQ,CAACZ,eAAe;QAC3B;IACF;IACA,MAAMA,cAAcwB,GAAG,CAACZ,MAAME;AAChC;AAEA,eAAeW,IAAId,IAAS,EAAEe,WAAyB;IACrD,MAAM,EAAEd,IAAI,EAAEM,QAAQ,EAAE,GAAG,MAAML,SAASF,KAAKG,MAAM;IAErD,MAAMa,eAAehB,KAAKG,MAAM,CAACK,KAAK,IAAIhC,QAAQ4B,WAAW,IAAIH;IAEjE,IAAIgB,QAAiBX;IACrB,IAAI,CAACC,YAAY,CAACS,cAAc;QAC9B,MAAME,SAAS,MAAMxB,aAAayB,IAAI,CAACnB,KAAKG,MAAM;QAClDc,QAAQ,MAAMC,OAAOJ,GAAG,CAAC;YACvB,GAAGd,IAAI;YACPe;QACF;QAEA,MAAMH,UAAUZ,KAAKG,MAAM,EAAEF;IAC/B;IAEA,OAAO;QACLmB,SAASb;QACTc,IAAIrB,KAAKG,MAAM,CAACkB,EAAE;QAClBpB;QACAgB;IACF;AACF;AAEAK,IAAAA,iCAAc,EAACR"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lage-run/scheduler",
3
- "version": "1.5.19",
3
+ "version": "1.5.21",
4
4
  "description": "Scheduler for Lage",
5
5
  "repository": {
6
6
  "type": "git",
@@ -18,17 +18,18 @@
18
18
  "lint": "monorepo-scripts lint"
19
19
  },
20
20
  "dependencies": {
21
- "@lage-run/cache": "^1.4.7",
22
- "@lage-run/config": "^0.9.0",
23
- "@lage-run/hasher": "^1.9.4",
21
+ "@lage-run/cache": "^1.4.9",
22
+ "@lage-run/config": "^0.9.2",
23
+ "@lage-run/hasher": "^1.9.6",
24
24
  "@lage-run/logger": "^1.3.3",
25
- "@lage-run/runners": "^1.3.1",
26
- "@lage-run/target-graph": "^0.13.0",
27
- "@lage-run/worker-threads-pool": "^0.9.3"
25
+ "@lage-run/runners": "^1.4.1",
26
+ "@lage-run/target-graph": "^0.14.1",
27
+ "@lage-run/worker-threads-pool": "^0.9.4"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@lage-run/monorepo-scripts": "^1.0.0",
31
- "@lage-run/scheduler-types": "^0.3.30"
31
+ "@lage-run/scheduler-types": "^0.3.32",
32
+ "@lage-run/test-utilities": "^0.1.0"
32
33
  },
33
34
  "files": [
34
35
  "lib/!(__*)",
@@ -1 +0,0 @@
1
- export declare const isRunningFromCI: boolean;
@@ -1,11 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- Object.defineProperty(exports, "isRunningFromCI", {
6
- enumerable: true,
7
- get: function() {
8
- return isRunningFromCI;
9
- }
10
- });
11
- const isRunningFromCI = process.env.NODE_ENV !== "test" && (!!process.env.CI || !!process.env.TF_BUILD);
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/cache/isRunningFromCI.ts"],"sourcesContent":["export const isRunningFromCI: boolean = process.env.NODE_ENV !== \"test\" && (!!process.env.CI || !!process.env.TF_BUILD);\n"],"names":["isRunningFromCI","process","env","NODE_ENV","CI","TF_BUILD"],"mappings":";;;;+BAAaA;;;eAAAA;;;AAAN,MAAMA,kBAA2BC,QAAQC,GAAG,CAACC,QAAQ,KAAK,UAAW,CAAA,CAAC,CAACF,QAAQC,GAAG,CAACE,EAAE,IAAI,CAAC,CAACH,QAAQC,GAAG,CAACG,QAAQ,AAAD"}