@backendkit-labs/pipeline 0.1.1 → 0.3.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.
@@ -1,10 +1,35 @@
1
- import { __decorateClass, Pipeline } from '../chunk-GHWTXTUB.js';
1
+ import { __decorateClass, Pipeline } from '../chunk-GTIMFVE5.js';
2
2
  import { Module, Inject } from '@nestjs/common';
3
3
 
4
+ function validatePipelineDefinition(def, index) {
5
+ if (!def.token) {
6
+ throw new Error(
7
+ `Pipeline definition at index ${index} is missing "token". Use definePipeline() to create one.`
8
+ );
9
+ }
10
+ if (!Array.isArray(def.steps) || def.steps.length === 0) {
11
+ throw new Error(
12
+ `Pipeline "${def.token.description ?? index}" has no steps. Provide at least one step class.`
13
+ );
14
+ }
15
+ for (let i = 0; i < def.steps.length; i++) {
16
+ const step = def.steps[i];
17
+ if (typeof step !== "function") {
18
+ throw new Error(
19
+ `Step at index ${i} in pipeline "${def.token.description ?? index}" is not a class/constructor. Expected a Type<PipelineStep>, got ${typeof step}.`
20
+ );
21
+ }
22
+ }
23
+ }
24
+ function isPipelineStep(instance) {
25
+ return typeof instance === "object" && instance !== null && typeof instance.handle === "function";
26
+ }
4
27
  var PipelineModule = class {
5
28
  static forRoot(options) {
6
29
  const providers = [];
7
- for (const def of options.pipelines) {
30
+ for (let i = 0; i < options.pipelines.length; i++) {
31
+ const def = options.pipelines[i];
32
+ validatePipelineDefinition(def, i);
8
33
  for (const step of def.steps) {
9
34
  providers.push({ provide: step, useClass: step });
10
35
  }
@@ -12,7 +37,14 @@ var PipelineModule = class {
12
37
  provide: def.token.symbol,
13
38
  useFactory: (...stepInstances) => {
14
39
  const p = new Pipeline(def.options ?? {});
15
- for (const instance of stepInstances) {
40
+ for (let j = 0; j < stepInstances.length; j++) {
41
+ const instance = stepInstances[j];
42
+ if (!isPipelineStep(instance)) {
43
+ const stepName = def.steps[j]?.name ?? String(j);
44
+ throw new Error(
45
+ `Step "${stepName}" in pipeline "${def.token.description}" does not implement PipelineStep. Expected a class with a "handle(ctx)" method.`
46
+ );
47
+ }
16
48
  p.pipe(instance);
17
49
  }
18
50
  return p;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/nestjs/pipeline.module.ts","../../src/nestjs/pipeline.decorator.ts"],"names":[],"mappings":";;;AAMO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,OAAO,QAAQ,OAAA,EAA+C;AAC5D,IAAA,MAAM,YAAwB,EAAC;AAE/B,IAAA,KAAA,MAAW,GAAA,IAAO,QAAQ,SAAA,EAAW;AACnC,MAAA,KAAA,MAAW,IAAA,IAAQ,IAAI,KAAA,EAAO;AAC5B,QAAA,SAAA,CAAU,KAAK,EAAE,OAAA,EAAS,IAAA,EAAM,QAAA,EAAU,MAAM,CAAA;AAAA,MAClD;AAEA,MAAA,SAAA,CAAU,IAAA,CAAK;AAAA,QACb,OAAA,EAAY,IAAI,KAAA,CAAM,MAAA;AAAA,QACtB,UAAA,EAAY,IAAI,aAAA,KAAoD;AAClE,UAAA,MAAM,IAAI,IAAI,QAAA,CAAS,GAAA,CAAI,OAAA,IAAW,EAAE,CAAA;AACxC,UAAA,KAAA,MAAW,YAAY,aAAA,EAAe;AACpC,YAAA,CAAA,CAAE,KAAK,QAAQ,CAAA;AAAA,UACjB;AACA,UAAA,OAAO,CAAA;AAAA,QACT,CAAA;AAAA,QACA,QAAQ,GAAA,CAAI;AAAA,OACb,CAAA;AAAA,IACH;AAEA,IAAA,OAAO;AAAA,MACL,MAAA,EAAW,cAAA;AAAA,MACX,SAAA;AAAA,MACA,OAAA,EAAW,SAAA;AAAA,MACX,MAAA,EAAW;AAAA,KACb;AAAA,EACF;AACF;AA7Ba,cAAA,GAAN,eAAA,CAAA;AAAA,EADN,MAAA,CAAO,EAAE;AAAA,CAAA,EACG,cAAA,CAAA;ACHN,IAAM,cAAA,GAAiB,CAC5B,KAAA,KAC8B,MAAA,CAAO,MAAM,MAAM","file":"index.js","sourcesContent":["import { DynamicModule, Module, Provider } from '@nestjs/common';\nimport { Pipeline } from '../core/pipeline.js';\nimport type { PipelineStep } from '../core/types.js';\nimport type { PipelineModuleOptions } from './pipeline.options.js';\n\n@Module({})\nexport class PipelineModule {\n static forRoot(options: PipelineModuleOptions): DynamicModule {\n const providers: Provider[] = [];\n\n for (const def of options.pipelines) {\n for (const step of def.steps) {\n providers.push({ provide: step, useClass: step });\n }\n\n providers.push({\n provide: def.token.symbol,\n useFactory: (...stepInstances: PipelineStep<unknown, unknown>[]) => {\n const p = new Pipeline(def.options ?? {});\n for (const instance of stepInstances) {\n p.pipe(instance);\n }\n return p;\n },\n inject: def.steps,\n });\n }\n\n return {\n module: PipelineModule,\n providers,\n exports: providers,\n global: true,\n };\n }\n}\n","import { Inject } from '@nestjs/common';\nimport type { PipelineToken } from '../core/define-pipeline.js';\n\nexport const InjectPipeline = <TContext, TError>(\n token: PipelineToken<TContext, TError>,\n): ReturnType<typeof Inject> => Inject(token.symbol);\n"]}
1
+ {"version":3,"sources":["../../src/nestjs/pipeline.module.ts","../../src/nestjs/pipeline.decorator.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { DynamicModule, Module, Provider, Type } from '@nestjs/common';\nimport { Pipeline } from '../core/pipeline.js';\nimport type { PipelineStep } from '../core/types.js';\nimport type { PipelineDefinition, PipelineModuleOptions } from './pipeline.options.js';\n\nfunction validatePipelineDefinition(\n def: PipelineDefinition,\n index: number,\n): void {\n if (!def.token) {\n throw new Error(\n `Pipeline definition at index ${index} is missing \"token\". Use definePipeline() to create one.`,\n );\n }\n\n if (!Array.isArray(def.steps) || def.steps.length === 0) {\n throw new Error(\n `Pipeline \"${def.token.description ?? index}\" has no steps. Provide at least one step class.`,\n );\n }\n\n for (let i = 0; i < def.steps.length; i++) {\n const step = def.steps[i];\n if (typeof step !== 'function') {\n throw new Error(\n `Step at index ${i} in pipeline \"${def.token.description ?? index}\" is not a class/constructor. ` +\n `Expected a Type<PipelineStep>, got ${typeof step}.`,\n );\n }\n }\n}\n\nfunction isPipelineStep(instance: unknown): instance is PipelineStep<unknown, unknown> {\n return (\n typeof instance === 'object' &&\n instance !== null &&\n typeof (instance as PipelineStep<unknown, unknown>).handle === 'function'\n );\n}\n\n@Module({})\nexport class PipelineModule {\n static forRoot(options: PipelineModuleOptions): DynamicModule {\n const providers: Provider[] = [];\n\n for (let i = 0; i < options.pipelines.length; i++) {\n const def = options.pipelines[i];\n validatePipelineDefinition(def, i);\n\n for (const step of def.steps) {\n providers.push({ provide: step as Type, useClass: step as Type });\n }\n\n providers.push({\n provide: def.token.symbol,\n useFactory: (...stepInstances: unknown[]) => {\n const p = new Pipeline(def.options ?? {});\n\n for (let j = 0; j < stepInstances.length; j++) {\n const instance = stepInstances[j];\n\n if (!isPipelineStep(instance)) {\n const stepName = (def.steps[j] as Type)?.name ?? String(j);\n throw new Error(\n `Step \"${stepName}\" in pipeline \"${def.token.description}\" does not implement PipelineStep. ` +\n `Expected a class with a \"handle(ctx)\" method.`,\n );\n }\n\n p.pipe(instance);\n }\n\n return p;\n },\n inject: def.steps as Type[],\n });\n }\n\n return {\n module: PipelineModule,\n providers,\n exports: providers,\n global: true,\n };\n }\n}\n","import { Inject } from '@nestjs/common';\nimport type { PipelineToken } from '../core/define-pipeline.js';\n\nexport const InjectPipeline = <TContext, TError>(\n token: PipelineToken<TContext, TError>,\n): ReturnType<typeof Inject> => Inject(token.symbol);\n"]}
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@backendkit-labs/pipeline",
3
- "version": "0.1.1",
3
+ "version": "0.3.0",
4
4
  "license": "Apache-2.0",
5
5
  "author": {
6
6
  "name": "BackendKit Labs",
7
- "email": "backendkit.dev@gmail.com"
7
+ "email": "hello@backendkitlabs.dev"
8
8
  },
9
9
  "description": "Type-safe async pipeline — Chain of Responsibility with stop-on-first / collect-all modes, conditional steps, observability hooks, and optional NestJS integration",
10
10
  "type": "module",
@@ -49,14 +49,14 @@
49
49
  "node",
50
50
  "pattern"
51
51
  ],
52
- "homepage": "https://github.com/backendkit-dev/backendkit-monorepo/tree/master/packages/pipeline#readme",
52
+ "homepage": "https://backendkitlabs.dev/docs/pipeline/",
53
53
  "repository": {
54
54
  "type": "git",
55
- "url": "git+https://github.com/backendkit-dev/backendkit-monorepo.git",
55
+ "url": "git+https://github.com/BackendKit-labs/backendkit-monorepo.git",
56
56
  "directory": "packages/pipeline"
57
57
  },
58
58
  "bugs": {
59
- "url": "https://github.com/backendkit-dev/backendkit-monorepo/issues"
59
+ "url": "https://github.com/BackendKit-labs/backendkit-monorepo/issues"
60
60
  },
61
61
  "publishConfig": {
62
62
  "access": "public"
@@ -85,6 +85,7 @@
85
85
  "@eslint/js": "^9.39.4",
86
86
  "@nestjs/common": "^10.0.0",
87
87
  "@nestjs/core": "^10.0.0",
88
+ "@nestjs/testing": "^10.4.22",
88
89
  "@types/node": "^22.0.0",
89
90
  "eslint": "^9.0.0",
90
91
  "reflect-metadata": "^0.2.0",
@@ -1,93 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
- var __decorateClass = (decorators, target, key, kind) => {
4
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
5
- for (var i = decorators.length - 1, decorator; i >= 0; i--)
6
- if (decorator = decorators[i])
7
- result = (kind ? decorator(target, key, result) : decorator(result)) || result;
8
- if (kind && result) __defProp(target, key, result);
9
- return result;
10
- };
11
-
12
- // src/core/pipeline.ts
13
- var Pipeline = class {
14
- entries = [];
15
- options;
16
- constructor(options = {}) {
17
- this.options = options;
18
- }
19
- pipe(step) {
20
- this.entries.push({
21
- instance: step,
22
- name: step.stepName ?? step.constructor.name
23
- });
24
- return this;
25
- }
26
- pipeIf(condition, step) {
27
- this.entries.push({
28
- instance: step,
29
- name: step.stepName ?? step.constructor.name,
30
- condition
31
- });
32
- return this;
33
- }
34
- async run(initialCtx) {
35
- const start = Date.now();
36
- const { mode = "stop-on-first", onStep, onStepComplete, onError, onComplete } = this.options;
37
- const executedSteps = [];
38
- const failures = [];
39
- let ctx = initialCtx;
40
- for (const { instance, name, condition } of this.entries) {
41
- if (condition && !condition(ctx)) continue;
42
- await onStep?.(name, ctx);
43
- const stepStart = Date.now();
44
- const stepResult = await instance.handle(ctx);
45
- const stepMs = Date.now() - stepStart;
46
- if (!stepResult.ok) {
47
- await onError?.(name, stepResult.error);
48
- failures.push({ step: name, cause: stepResult.error });
49
- if (mode === "stop-on-first") {
50
- return {
51
- ok: false,
52
- error: {
53
- mode,
54
- failedStep: name,
55
- cause: stepResult.error,
56
- executedSteps: [...executedSteps],
57
- durationMs: Date.now() - start,
58
- failures
59
- }
60
- };
61
- }
62
- executedSteps.push(name);
63
- continue;
64
- }
65
- ctx = stepResult.value;
66
- executedSteps.push(name);
67
- await onStepComplete?.(name, ctx, stepMs);
68
- }
69
- if (failures.length > 0) {
70
- return {
71
- ok: false,
72
- error: {
73
- mode,
74
- failedStep: failures[0].step,
75
- cause: failures[0].cause,
76
- executedSteps: [...executedSteps],
77
- durationMs: Date.now() - start,
78
- failures
79
- }
80
- };
81
- }
82
- const durationMs = Date.now() - start;
83
- await onComplete?.(ctx, durationMs);
84
- return { ok: true, value: ctx, executedSteps: [...executedSteps], durationMs };
85
- }
86
- };
87
- function pipeline(options) {
88
- return new Pipeline(options);
89
- }
90
-
91
- export { Pipeline, __decorateClass, pipeline };
92
- //# sourceMappingURL=chunk-GHWTXTUB.js.map
93
- //# sourceMappingURL=chunk-GHWTXTUB.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/pipeline.ts"],"names":[],"mappings":"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","file":"chunk-GHWTXTUB.js","sourcesContent":["import type {\n PipelineOptions,\n PipelineRunResult,\n PipelineStep,\n PipelineStepFailure,\n} from './types.js';\n\ninterface StepEntry<TContext, TError> {\n instance: PipelineStep<TContext, TError>;\n name: string;\n condition?: (ctx: TContext) => boolean;\n}\n\nexport class Pipeline<TContext, TError = unknown> {\n private readonly entries: StepEntry<TContext, TError>[] = [];\n private readonly options: PipelineOptions<TContext, TError>;\n\n constructor(options: PipelineOptions<TContext, TError> = {}) {\n this.options = options;\n }\n\n pipe(step: PipelineStep<TContext, TError>): this {\n this.entries.push({\n instance: step,\n name: step.stepName ?? step.constructor.name,\n });\n return this;\n }\n\n pipeIf(condition: (ctx: TContext) => boolean, step: PipelineStep<TContext, TError>): this {\n this.entries.push({\n instance: step,\n name: step.stepName ?? step.constructor.name,\n condition,\n });\n return this;\n }\n\n async run(initialCtx: TContext): Promise<PipelineRunResult<TContext, TError>> {\n const start = Date.now();\n const { mode = 'stop-on-first', onStep, onStepComplete, onError, onComplete } = this.options;\n const executedSteps: string[] = [];\n const failures: PipelineStepFailure<TError>[] = [];\n let ctx = initialCtx;\n\n for (const { instance, name, condition } of this.entries) {\n if (condition && !condition(ctx)) continue;\n\n await onStep?.(name, ctx);\n const stepStart = Date.now();\n const stepResult = await instance.handle(ctx);\n const stepMs = Date.now() - stepStart;\n\n if (!stepResult.ok) {\n await onError?.(name, stepResult.error);\n failures.push({ step: name, cause: stepResult.error });\n\n if (mode === 'stop-on-first') {\n return {\n ok: false,\n error: {\n mode,\n failedStep: name,\n cause: stepResult.error,\n executedSteps: [...executedSteps],\n durationMs: Date.now() - start,\n failures,\n },\n };\n }\n\n // collect-all: record the failed step and continue\n executedSteps.push(name);\n continue;\n }\n\n ctx = stepResult.value;\n executedSteps.push(name);\n await onStepComplete?.(name, ctx, stepMs);\n }\n\n if (failures.length > 0) {\n return {\n ok: false,\n error: {\n mode,\n failedStep: failures[0].step,\n cause: failures[0].cause,\n executedSteps: [...executedSteps],\n durationMs: Date.now() - start,\n failures,\n },\n };\n }\n\n const durationMs = Date.now() - start;\n await onComplete?.(ctx, durationMs);\n return { ok: true, value: ctx, executedSteps: [...executedSteps], durationMs };\n }\n}\n\nexport function pipeline<TContext, TError = unknown>(\n options?: PipelineOptions<TContext, TError>,\n): Pipeline<TContext, TError> {\n return new Pipeline(options);\n}\n"]}
@@ -1,97 +0,0 @@
1
- 'use strict';
2
-
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __decorateClass = (decorators, target, key, kind) => {
6
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
7
- for (var i = decorators.length - 1, decorator; i >= 0; i--)
8
- if (decorator = decorators[i])
9
- result = (kind ? decorator(target, key, result) : decorator(result)) || result;
10
- if (kind && result) __defProp(target, key, result);
11
- return result;
12
- };
13
-
14
- // src/core/pipeline.ts
15
- var Pipeline = class {
16
- entries = [];
17
- options;
18
- constructor(options = {}) {
19
- this.options = options;
20
- }
21
- pipe(step) {
22
- this.entries.push({
23
- instance: step,
24
- name: step.stepName ?? step.constructor.name
25
- });
26
- return this;
27
- }
28
- pipeIf(condition, step) {
29
- this.entries.push({
30
- instance: step,
31
- name: step.stepName ?? step.constructor.name,
32
- condition
33
- });
34
- return this;
35
- }
36
- async run(initialCtx) {
37
- const start = Date.now();
38
- const { mode = "stop-on-first", onStep, onStepComplete, onError, onComplete } = this.options;
39
- const executedSteps = [];
40
- const failures = [];
41
- let ctx = initialCtx;
42
- for (const { instance, name, condition } of this.entries) {
43
- if (condition && !condition(ctx)) continue;
44
- await onStep?.(name, ctx);
45
- const stepStart = Date.now();
46
- const stepResult = await instance.handle(ctx);
47
- const stepMs = Date.now() - stepStart;
48
- if (!stepResult.ok) {
49
- await onError?.(name, stepResult.error);
50
- failures.push({ step: name, cause: stepResult.error });
51
- if (mode === "stop-on-first") {
52
- return {
53
- ok: false,
54
- error: {
55
- mode,
56
- failedStep: name,
57
- cause: stepResult.error,
58
- executedSteps: [...executedSteps],
59
- durationMs: Date.now() - start,
60
- failures
61
- }
62
- };
63
- }
64
- executedSteps.push(name);
65
- continue;
66
- }
67
- ctx = stepResult.value;
68
- executedSteps.push(name);
69
- await onStepComplete?.(name, ctx, stepMs);
70
- }
71
- if (failures.length > 0) {
72
- return {
73
- ok: false,
74
- error: {
75
- mode,
76
- failedStep: failures[0].step,
77
- cause: failures[0].cause,
78
- executedSteps: [...executedSteps],
79
- durationMs: Date.now() - start,
80
- failures
81
- }
82
- };
83
- }
84
- const durationMs = Date.now() - start;
85
- await onComplete?.(ctx, durationMs);
86
- return { ok: true, value: ctx, executedSteps: [...executedSteps], durationMs };
87
- }
88
- };
89
- function pipeline(options) {
90
- return new Pipeline(options);
91
- }
92
-
93
- exports.Pipeline = Pipeline;
94
- exports.__decorateClass = __decorateClass;
95
- exports.pipeline = pipeline;
96
- //# sourceMappingURL=chunk-LPCHUZQE.cjs.map
97
- //# sourceMappingURL=chunk-LPCHUZQE.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/pipeline.ts"],"names":[],"mappings":"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","file":"chunk-LPCHUZQE.cjs","sourcesContent":["import type {\n PipelineOptions,\n PipelineRunResult,\n PipelineStep,\n PipelineStepFailure,\n} from './types.js';\n\ninterface StepEntry<TContext, TError> {\n instance: PipelineStep<TContext, TError>;\n name: string;\n condition?: (ctx: TContext) => boolean;\n}\n\nexport class Pipeline<TContext, TError = unknown> {\n private readonly entries: StepEntry<TContext, TError>[] = [];\n private readonly options: PipelineOptions<TContext, TError>;\n\n constructor(options: PipelineOptions<TContext, TError> = {}) {\n this.options = options;\n }\n\n pipe(step: PipelineStep<TContext, TError>): this {\n this.entries.push({\n instance: step,\n name: step.stepName ?? step.constructor.name,\n });\n return this;\n }\n\n pipeIf(condition: (ctx: TContext) => boolean, step: PipelineStep<TContext, TError>): this {\n this.entries.push({\n instance: step,\n name: step.stepName ?? step.constructor.name,\n condition,\n });\n return this;\n }\n\n async run(initialCtx: TContext): Promise<PipelineRunResult<TContext, TError>> {\n const start = Date.now();\n const { mode = 'stop-on-first', onStep, onStepComplete, onError, onComplete } = this.options;\n const executedSteps: string[] = [];\n const failures: PipelineStepFailure<TError>[] = [];\n let ctx = initialCtx;\n\n for (const { instance, name, condition } of this.entries) {\n if (condition && !condition(ctx)) continue;\n\n await onStep?.(name, ctx);\n const stepStart = Date.now();\n const stepResult = await instance.handle(ctx);\n const stepMs = Date.now() - stepStart;\n\n if (!stepResult.ok) {\n await onError?.(name, stepResult.error);\n failures.push({ step: name, cause: stepResult.error });\n\n if (mode === 'stop-on-first') {\n return {\n ok: false,\n error: {\n mode,\n failedStep: name,\n cause: stepResult.error,\n executedSteps: [...executedSteps],\n durationMs: Date.now() - start,\n failures,\n },\n };\n }\n\n // collect-all: record the failed step and continue\n executedSteps.push(name);\n continue;\n }\n\n ctx = stepResult.value;\n executedSteps.push(name);\n await onStepComplete?.(name, ctx, stepMs);\n }\n\n if (failures.length > 0) {\n return {\n ok: false,\n error: {\n mode,\n failedStep: failures[0].step,\n cause: failures[0].cause,\n executedSteps: [...executedSteps],\n durationMs: Date.now() - start,\n failures,\n },\n };\n }\n\n const durationMs = Date.now() - start;\n await onComplete?.(ctx, durationMs);\n return { ok: true, value: ctx, executedSteps: [...executedSteps], durationMs };\n }\n}\n\nexport function pipeline<TContext, TError = unknown>(\n options?: PipelineOptions<TContext, TError>,\n): Pipeline<TContext, TError> {\n return new Pipeline(options);\n}\n"]}