@teamflojo/floimg 0.1.0
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.
- package/LICENSE +21 -0
- package/dist/cli/commands/config.d.ts +3 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +165 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/filter.d.ts +4 -0
- package/dist/cli/commands/filter.d.ts.map +1 -0
- package/dist/cli/commands/filter.js +102 -0
- package/dist/cli/commands/filter.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +3 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +49 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/commands/mcp.d.ts +3 -0
- package/dist/cli/commands/mcp.d.ts.map +1 -0
- package/dist/cli/commands/mcp.js +88 -0
- package/dist/cli/commands/mcp.js.map +1 -0
- package/dist/cli/commands/plugins.d.ts +3 -0
- package/dist/cli/commands/plugins.d.ts.map +1 -0
- package/dist/cli/commands/plugins.js +66 -0
- package/dist/cli/commands/plugins.js.map +1 -0
- package/dist/cli/commands/run.d.ts +3 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +45 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/save.d.ts +3 -0
- package/dist/cli/commands/save.d.ts.map +1 -0
- package/dist/cli/commands/save.js +54 -0
- package/dist/cli/commands/save.js.map +1 -0
- package/dist/cli/commands/text.d.ts +3 -0
- package/dist/cli/commands/text.d.ts.map +1 -0
- package/dist/cli/commands/text.js +143 -0
- package/dist/cli/commands/text.js.map +1 -0
- package/dist/cli/commands/transform.d.ts +3 -0
- package/dist/cli/commands/transform.d.ts.map +1 -0
- package/dist/cli/commands/transform.js +59 -0
- package/dist/cli/commands/transform.js.map +1 -0
- package/dist/cli/commands/upload.d.ts +3 -0
- package/dist/cli/commands/upload.d.ts.map +1 -0
- package/dist/cli/commands/upload.js +59 -0
- package/dist/cli/commands/upload.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +139 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config/index.d.ts +10 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +38 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +23 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +189 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/core/client.d.ts +63 -0
- package/dist/core/client.d.ts.map +1 -0
- package/dist/core/client.js +318 -0
- package/dist/core/client.js.map +1 -0
- package/dist/core/errors.d.ts +38 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +75 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/logger.d.ts +12 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +26 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/pipeline-runner.d.ts +64 -0
- package/dist/core/pipeline-runner.d.ts.map +1 -0
- package/dist/core/pipeline-runner.js +109 -0
- package/dist/core/pipeline-runner.js.map +1 -0
- package/dist/core/types.d.ts +392 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +5 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +49 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/server.d.ts +3 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +731 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/providers/ai/index.d.ts +3 -0
- package/dist/providers/ai/index.d.ts.map +1 -0
- package/dist/providers/ai/index.js +2 -0
- package/dist/providers/ai/index.js.map +1 -0
- package/dist/providers/ai/openai.d.ts +44 -0
- package/dist/providers/ai/openai.d.ts.map +1 -0
- package/dist/providers/ai/openai.js +133 -0
- package/dist/providers/ai/openai.js.map +1 -0
- package/dist/providers/save/FsSaveProvider.d.ts +20 -0
- package/dist/providers/save/FsSaveProvider.d.ts.map +1 -0
- package/dist/providers/save/FsSaveProvider.js +34 -0
- package/dist/providers/save/FsSaveProvider.js.map +1 -0
- package/dist/providers/save/S3SaveProvider.d.ts +26 -0
- package/dist/providers/save/S3SaveProvider.d.ts.map +1 -0
- package/dist/providers/save/S3SaveProvider.js +42 -0
- package/dist/providers/save/S3SaveProvider.js.map +1 -0
- package/dist/providers/store/fs.d.ts +20 -0
- package/dist/providers/store/fs.d.ts.map +1 -0
- package/dist/providers/store/fs.js +42 -0
- package/dist/providers/store/fs.js.map +1 -0
- package/dist/providers/store/index.d.ts +3 -0
- package/dist/providers/store/index.d.ts.map +1 -0
- package/dist/providers/store/index.js +3 -0
- package/dist/providers/store/index.js.map +1 -0
- package/dist/providers/store/s3.d.ts +62 -0
- package/dist/providers/store/s3.d.ts.map +1 -0
- package/dist/providers/store/s3.js +92 -0
- package/dist/providers/store/s3.js.map +1 -0
- package/dist/providers/svg/index.d.ts +2 -0
- package/dist/providers/svg/index.d.ts.map +1 -0
- package/dist/providers/svg/index.js +2 -0
- package/dist/providers/svg/index.js.map +1 -0
- package/dist/providers/svg/shapes.d.ts +18 -0
- package/dist/providers/svg/shapes.d.ts.map +1 -0
- package/dist/providers/svg/shapes.js +161 -0
- package/dist/providers/svg/shapes.js.map +1 -0
- package/dist/providers/transform/index.d.ts +2 -0
- package/dist/providers/transform/index.d.ts.map +1 -0
- package/dist/providers/transform/index.js +2 -0
- package/dist/providers/transform/index.js.map +1 -0
- package/dist/providers/transform/presets.d.ts +44 -0
- package/dist/providers/transform/presets.d.ts.map +1 -0
- package/dist/providers/transform/presets.js +205 -0
- package/dist/providers/transform/presets.js.map +1 -0
- package/dist/providers/transform/sharp.d.ts +64 -0
- package/dist/providers/transform/sharp.d.ts.map +1 -0
- package/dist/providers/transform/sharp.js +732 -0
- package/dist/providers/transform/sharp.js.map +1 -0
- package/dist/providers/transform/text.d.ts +38 -0
- package/dist/providers/transform/text.d.ts.map +1 -0
- package/dist/providers/transform/text.js +116 -0
- package/dist/providers/transform/text.js.map +1 -0
- package/package.json +84 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base error class for floimg errors
|
|
3
|
+
*/
|
|
4
|
+
export class FloimgError extends Error {
|
|
5
|
+
code;
|
|
6
|
+
constructor(message, code) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.code = code;
|
|
9
|
+
this.name = "FloimgError";
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Error thrown when a provider is not found
|
|
14
|
+
*/
|
|
15
|
+
export class ProviderNotFoundError extends FloimgError {
|
|
16
|
+
constructor(providerType, providerName) {
|
|
17
|
+
let message = `Provider "${providerName}" not found for type "${providerType}"`;
|
|
18
|
+
// Add helpful hints for common cases
|
|
19
|
+
if (providerType === "save" && (providerName === "s3" || providerName === "r2" || providerName === "tigris")) {
|
|
20
|
+
message += `\n\nTo enable S3-compatible storage, create a floimg.config.ts file:\n\n` +
|
|
21
|
+
`export default {\n` +
|
|
22
|
+
` save: {\n` +
|
|
23
|
+
` s3: {\n` +
|
|
24
|
+
` bucket: 'my-bucket',\n` +
|
|
25
|
+
` region: 'us-east-1',\n` +
|
|
26
|
+
` credentials: {\n` +
|
|
27
|
+
` accessKeyId: process.env.AWS_ACCESS_KEY_ID,\n` +
|
|
28
|
+
` secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,\n` +
|
|
29
|
+
` },\n` +
|
|
30
|
+
` },\n` +
|
|
31
|
+
` },\n` +
|
|
32
|
+
`};\n\n` +
|
|
33
|
+
`See floimg.config.example.ts for more options.`;
|
|
34
|
+
}
|
|
35
|
+
super(message, "PROVIDER_NOT_FOUND");
|
|
36
|
+
this.name = "ProviderNotFoundError";
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Error thrown when provider configuration is invalid
|
|
41
|
+
*/
|
|
42
|
+
export class ConfigurationError extends FloimgError {
|
|
43
|
+
constructor(message) {
|
|
44
|
+
super(message, "CONFIGURATION_ERROR");
|
|
45
|
+
this.name = "ConfigurationError";
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Error thrown when an image transformation fails
|
|
50
|
+
*/
|
|
51
|
+
export class TransformError extends FloimgError {
|
|
52
|
+
constructor(message) {
|
|
53
|
+
super(message, "TRANSFORM_ERROR");
|
|
54
|
+
this.name = "TransformError";
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Error thrown when an upload operation fails
|
|
59
|
+
*/
|
|
60
|
+
export class UploadError extends FloimgError {
|
|
61
|
+
constructor(message) {
|
|
62
|
+
super(message, "UPLOAD_ERROR");
|
|
63
|
+
this.name = "UploadError";
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Error thrown when image generation fails
|
|
68
|
+
*/
|
|
69
|
+
export class GenerationError extends FloimgError {
|
|
70
|
+
constructor(message) {
|
|
71
|
+
super(message, "GENERATION_ERROR");
|
|
72
|
+
this.name = "GenerationError";
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,WAAY,SAAQ,KAAK;IACA;IAApC,YAAY,OAAe,EAAS,IAAa;QAC/C,KAAK,CAAC,OAAO,CAAC,CAAC;QADmB,SAAI,GAAJ,IAAI,CAAS;QAE/C,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,qBAAsB,SAAQ,WAAW;IACpD,YAAY,YAAoB,EAAE,YAAoB;QACpD,IAAI,OAAO,GAAG,aAAa,YAAY,yBAAyB,YAAY,GAAG,CAAC;QAEhF,qCAAqC;QACrC,IAAI,YAAY,KAAK,MAAM,IAAI,CAAC,YAAY,KAAK,IAAI,IAAI,YAAY,KAAK,IAAI,IAAI,YAAY,KAAK,QAAQ,CAAC,EAAE,CAAC;YAC7G,OAAO,IAAI,0EAA0E;gBACnF,oBAAoB;gBACpB,aAAa;gBACb,aAAa;gBACb,8BAA8B;gBAC9B,8BAA8B;gBAC9B,wBAAwB;gBACxB,uDAAuD;gBACvD,+DAA+D;gBAC/D,YAAY;gBACZ,UAAU;gBACV,QAAQ;gBACR,QAAQ;gBACR,gDAAgD,CAAC;QACrD,CAAC;QAED,KAAK,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;IACtC,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,kBAAmB,SAAQ,WAAW;IACjD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAC;QACtC,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,cAAe,SAAQ,WAAW;IAC7C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;QAClC,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,WAAY,SAAQ,WAAW;IAC1C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;QAC/B,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,eAAgB,SAAQ,WAAW;IAC9C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple logger for imgflo
|
|
3
|
+
*/
|
|
4
|
+
export declare class Logger {
|
|
5
|
+
private verbose;
|
|
6
|
+
constructor(verbose?: boolean);
|
|
7
|
+
info(message: string, ...args: unknown[]): void;
|
|
8
|
+
warn(message: string, ...args: unknown[]): void;
|
|
9
|
+
error(message: string, ...args: unknown[]): void;
|
|
10
|
+
debug(message: string, ...args: unknown[]): void;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/core/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,MAAM;IACL,OAAO,CAAC,OAAO;gBAAP,OAAO,GAAE,OAAe;IAE5C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAM/C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI/C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAIhD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;CAKjD"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple logger for imgflo
|
|
3
|
+
*/
|
|
4
|
+
export class Logger {
|
|
5
|
+
verbose;
|
|
6
|
+
constructor(verbose = false) {
|
|
7
|
+
this.verbose = verbose;
|
|
8
|
+
}
|
|
9
|
+
info(message, ...args) {
|
|
10
|
+
if (this.verbose) {
|
|
11
|
+
console.log(`[imgflo] ${message}`, ...args);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
warn(message, ...args) {
|
|
15
|
+
console.warn(`[imgflo] ${message}`, ...args);
|
|
16
|
+
}
|
|
17
|
+
error(message, ...args) {
|
|
18
|
+
console.error(`[imgflo] ${message}`, ...args);
|
|
19
|
+
}
|
|
20
|
+
debug(message, ...args) {
|
|
21
|
+
if (this.verbose) {
|
|
22
|
+
console.debug(`[imgflo] ${message}`, ...args);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/core/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,MAAM;IACG;IAApB,YAAoB,UAAmB,KAAK;QAAxB,YAAO,GAAP,OAAO,CAAiB;IAAG,CAAC;IAEhD,IAAI,CAAC,OAAe,EAAE,GAAG,IAAe;QACtC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,YAAY,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAG,IAAe;QACtC,OAAO,CAAC,IAAI,CAAC,YAAY,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAG,IAAe;QACvC,OAAO,CAAC,KAAK,CAAC,YAAY,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAG,IAAe;QACvC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO,CAAC,KAAK,CAAC,YAAY,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pipeline execution engine with parallel step support
|
|
3
|
+
*
|
|
4
|
+
* This module provides dependency analysis and parallel execution for imgflo pipelines.
|
|
5
|
+
* Steps are grouped into "waves" based on their dependencies, and each wave is executed
|
|
6
|
+
* concurrently (bounded by the pipeline's concurrency setting).
|
|
7
|
+
*/
|
|
8
|
+
import type { PipelineStep } from "./types.js";
|
|
9
|
+
/**
|
|
10
|
+
* Represents a step with its dependency information
|
|
11
|
+
*/
|
|
12
|
+
export interface StepNode {
|
|
13
|
+
/** Original index in the pipeline steps array */
|
|
14
|
+
index: number;
|
|
15
|
+
/** The pipeline step */
|
|
16
|
+
step: PipelineStep;
|
|
17
|
+
/** Variable names this step depends on (inputs) */
|
|
18
|
+
dependencies: Set<string>;
|
|
19
|
+
/** Variable names this step produces (outputs) */
|
|
20
|
+
outputs: string[];
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* A group of steps that can be executed in parallel
|
|
24
|
+
*/
|
|
25
|
+
export interface ExecutionWave {
|
|
26
|
+
/** Steps that can run concurrently */
|
|
27
|
+
steps: StepNode[];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Build a dependency graph from pipeline steps
|
|
31
|
+
*
|
|
32
|
+
* Analyzes each step to determine:
|
|
33
|
+
* - What variables it depends on (from `in` field)
|
|
34
|
+
* - What variables it produces (from `out` field)
|
|
35
|
+
*
|
|
36
|
+
* @param steps - Array of pipeline steps
|
|
37
|
+
* @returns Array of step nodes with dependency information
|
|
38
|
+
*/
|
|
39
|
+
export declare function buildDependencyGraph(steps: PipelineStep[]): StepNode[];
|
|
40
|
+
/**
|
|
41
|
+
* Compute execution waves from the dependency graph
|
|
42
|
+
*
|
|
43
|
+
* Groups steps into "waves" where:
|
|
44
|
+
* - All steps in a wave have their dependencies satisfied
|
|
45
|
+
* - All steps in a wave can run in parallel
|
|
46
|
+
* - Waves are executed sequentially
|
|
47
|
+
*
|
|
48
|
+
* @param nodes - Step nodes with dependency information
|
|
49
|
+
* @returns Array of execution waves
|
|
50
|
+
* @throws Error if circular dependency is detected
|
|
51
|
+
*/
|
|
52
|
+
export declare function computeExecutionWaves(nodes: StepNode[]): ExecutionWave[];
|
|
53
|
+
/**
|
|
54
|
+
* Execute tasks with bounded concurrency
|
|
55
|
+
*
|
|
56
|
+
* Runs tasks in parallel but limits the number of concurrent executions.
|
|
57
|
+
* If concurrency is Infinity, all tasks run in parallel.
|
|
58
|
+
*
|
|
59
|
+
* @param tasks - Array of async task functions
|
|
60
|
+
* @param concurrency - Maximum number of concurrent tasks
|
|
61
|
+
* @returns Array of results in the same order as tasks
|
|
62
|
+
*/
|
|
63
|
+
export declare function executeWithConcurrency<T>(tasks: (() => Promise<T>)[], concurrency: number): Promise<T[]>;
|
|
64
|
+
//# sourceMappingURL=pipeline-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline-runner.d.ts","sourceRoot":"","sources":["../../src/core/pipeline-runner.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,wBAAwB;IACxB,IAAI,EAAE,YAAY,CAAC;IACnB,mDAAmD;IACnD,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B,kDAAkD;IAClD,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,sCAAsC;IACtC,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,QAAQ,EAAE,CAuBtE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,aAAa,EAAE,CAwCxE;AAED;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,CAAC,CAAC,EAC5C,KAAK,EAAE,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,EAC3B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,CAAC,EAAE,CAAC,CAgBd"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pipeline execution engine with parallel step support
|
|
3
|
+
*
|
|
4
|
+
* This module provides dependency analysis and parallel execution for imgflo pipelines.
|
|
5
|
+
* Steps are grouped into "waves" based on their dependencies, and each wave is executed
|
|
6
|
+
* concurrently (bounded by the pipeline's concurrency setting).
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Build a dependency graph from pipeline steps
|
|
10
|
+
*
|
|
11
|
+
* Analyzes each step to determine:
|
|
12
|
+
* - What variables it depends on (from `in` field)
|
|
13
|
+
* - What variables it produces (from `out` field)
|
|
14
|
+
*
|
|
15
|
+
* @param steps - Array of pipeline steps
|
|
16
|
+
* @returns Array of step nodes with dependency information
|
|
17
|
+
*/
|
|
18
|
+
export function buildDependencyGraph(steps) {
|
|
19
|
+
return steps.map((step, index) => {
|
|
20
|
+
const dependencies = new Set();
|
|
21
|
+
const outputs = [];
|
|
22
|
+
if (step.kind === "generate") {
|
|
23
|
+
// Generate steps have no inputs, only output
|
|
24
|
+
outputs.push(step.out);
|
|
25
|
+
}
|
|
26
|
+
else if (step.kind === "transform") {
|
|
27
|
+
// Transform steps depend on their input variable
|
|
28
|
+
dependencies.add(step.in);
|
|
29
|
+
outputs.push(step.out);
|
|
30
|
+
}
|
|
31
|
+
else if (step.kind === "save") {
|
|
32
|
+
// Save steps depend on their input variable
|
|
33
|
+
dependencies.add(step.in);
|
|
34
|
+
// Save steps may optionally produce an output
|
|
35
|
+
if (step.out) {
|
|
36
|
+
outputs.push(step.out);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return { index, step, dependencies, outputs };
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Compute execution waves from the dependency graph
|
|
44
|
+
*
|
|
45
|
+
* Groups steps into "waves" where:
|
|
46
|
+
* - All steps in a wave have their dependencies satisfied
|
|
47
|
+
* - All steps in a wave can run in parallel
|
|
48
|
+
* - Waves are executed sequentially
|
|
49
|
+
*
|
|
50
|
+
* @param nodes - Step nodes with dependency information
|
|
51
|
+
* @returns Array of execution waves
|
|
52
|
+
* @throws Error if circular dependency is detected
|
|
53
|
+
*/
|
|
54
|
+
export function computeExecutionWaves(nodes) {
|
|
55
|
+
const waves = [];
|
|
56
|
+
const completed = new Set(); // Variables that have been produced
|
|
57
|
+
const remaining = new Set(nodes);
|
|
58
|
+
while (remaining.size > 0) {
|
|
59
|
+
const wave = [];
|
|
60
|
+
for (const node of remaining) {
|
|
61
|
+
// Check if all dependencies are satisfied
|
|
62
|
+
const satisfied = [...node.dependencies].every((dep) => completed.has(dep));
|
|
63
|
+
if (satisfied) {
|
|
64
|
+
wave.push(node);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (wave.length === 0) {
|
|
68
|
+
// No progress can be made - circular dependency or missing input
|
|
69
|
+
const unsatisfied = [...remaining].map((n) => ({
|
|
70
|
+
step: n.step.kind,
|
|
71
|
+
needs: [...n.dependencies].filter((d) => !completed.has(d)),
|
|
72
|
+
}));
|
|
73
|
+
throw new Error(`Circular dependency or missing input detected in pipeline. ` +
|
|
74
|
+
`Unsatisfied steps: ${JSON.stringify(unsatisfied)}`);
|
|
75
|
+
}
|
|
76
|
+
// Remove wave nodes from remaining, add their outputs to completed
|
|
77
|
+
for (const node of wave) {
|
|
78
|
+
remaining.delete(node);
|
|
79
|
+
node.outputs.forEach((out) => completed.add(out));
|
|
80
|
+
}
|
|
81
|
+
waves.push({ steps: wave });
|
|
82
|
+
}
|
|
83
|
+
return waves;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Execute tasks with bounded concurrency
|
|
87
|
+
*
|
|
88
|
+
* Runs tasks in parallel but limits the number of concurrent executions.
|
|
89
|
+
* If concurrency is Infinity, all tasks run in parallel.
|
|
90
|
+
*
|
|
91
|
+
* @param tasks - Array of async task functions
|
|
92
|
+
* @param concurrency - Maximum number of concurrent tasks
|
|
93
|
+
* @returns Array of results in the same order as tasks
|
|
94
|
+
*/
|
|
95
|
+
export async function executeWithConcurrency(tasks, concurrency) {
|
|
96
|
+
if (concurrency === Infinity || concurrency >= tasks.length) {
|
|
97
|
+
// Run all tasks in parallel
|
|
98
|
+
return Promise.all(tasks.map((fn) => fn()));
|
|
99
|
+
}
|
|
100
|
+
// Run tasks in batches
|
|
101
|
+
const results = [];
|
|
102
|
+
for (let i = 0; i < tasks.length; i += concurrency) {
|
|
103
|
+
const batch = tasks.slice(i, i + concurrency);
|
|
104
|
+
const batchResults = await Promise.all(batch.map((fn) => fn()));
|
|
105
|
+
results.push(...batchResults);
|
|
106
|
+
}
|
|
107
|
+
return results;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=pipeline-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline-runner.js","sourceRoot":"","sources":["../../src/core/pipeline-runner.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA0BH;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAqB;IACxD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAC/B,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;QACvC,MAAM,OAAO,GAAa,EAAE,CAAC;QAE7B,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC7B,6CAA6C;YAC7C,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACrC,iDAAiD;YACjD,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAChC,4CAA4C;YAC5C,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC1B,8CAA8C;YAC9C,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC;IAChD,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAiB;IACrD,MAAM,KAAK,GAAoB,EAAE,CAAC;IAClC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC,CAAC,oCAAoC;IACzE,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IAEjC,OAAO,SAAS,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAe,EAAE,CAAC;QAE5B,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;YAC7B,0CAA0C;YAC1C,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CACrD,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CACnB,CAAC;YACF,IAAI,SAAS,EAAE,CAAC;gBACd,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,iEAAiE;YACjE,MAAM,WAAW,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC7C,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI;gBACjB,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;aAC5D,CAAC,CAAC,CAAC;YACJ,MAAM,IAAI,KAAK,CACb,6DAA6D;gBAC3D,sBAAsB,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,CACtD,CAAC;QACJ,CAAC;QAED,mEAAmE;QACnE,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;YACxB,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACvB,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QACpD,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,KAA2B,EAC3B,WAAmB;IAEnB,IAAI,WAAW,KAAK,QAAQ,IAAI,WAAW,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QAC5D,4BAA4B;QAC5B,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC9C,CAAC;IAED,uBAAuB;IACvB,MAAM,OAAO,GAAQ,EAAE,CAAC;IAExB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,WAAW,EAAE,CAAC;QACnD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC;QAC9C,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,CAAC;IAChC,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|