runsheet 0.4.0 → 0.5.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/README.md +195 -0
- package/dist/index.cjs +433 -51
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +217 -4
- package/dist/index.d.ts +217 -4
- package/dist/index.js +419 -51
- package/dist/index.js.map +1 -1
- package/llms.txt +138 -4
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -351,7 +351,7 @@ declare function defineStep<Requires extends StepContext, Provides extends StepC
|
|
|
351
351
|
* }
|
|
352
352
|
* ```
|
|
353
353
|
*/
|
|
354
|
-
type RunsheetErrorCode = 'REQUIRES_VALIDATION' | 'PROVIDES_VALIDATION' | 'ARGS_VALIDATION' | 'PREDICATE' | 'TIMEOUT' | 'RETRY_EXHAUSTED' | 'STRICT_OVERLAP';
|
|
354
|
+
type RunsheetErrorCode = 'REQUIRES_VALIDATION' | 'PROVIDES_VALIDATION' | 'ARGS_VALIDATION' | 'PREDICATE' | 'TIMEOUT' | 'RETRY_EXHAUSTED' | 'STRICT_OVERLAP' | 'CHOICE_NO_MATCH' | 'ROLLBACK' | 'UNKNOWN';
|
|
355
355
|
/**
|
|
356
356
|
* Base error class for all errors produced by the runsheet library.
|
|
357
357
|
*
|
|
@@ -361,8 +361,8 @@ type RunsheetErrorCode = 'REQUIRES_VALIDATION' | 'PROVIDES_VALIDATION' | 'ARGS_V
|
|
|
361
361
|
* library itself produced it.
|
|
362
362
|
*
|
|
363
363
|
* Use `instanceof RunsheetError` to distinguish library errors from
|
|
364
|
-
* application errors
|
|
365
|
-
* specific
|
|
364
|
+
* application errors. Use `instanceof` on a subclass (e.g.,
|
|
365
|
+
* `TimeoutError`) or check the `code` property for specific failures.
|
|
366
366
|
*/
|
|
367
367
|
declare class RunsheetError extends Error {
|
|
368
368
|
/** Discriminant code identifying the type of library error. */
|
|
@@ -373,6 +373,56 @@ declare class RunsheetError extends Error {
|
|
|
373
373
|
*/
|
|
374
374
|
constructor(code: RunsheetErrorCode, message: string);
|
|
375
375
|
}
|
|
376
|
+
/** Schema validation failed on the accumulated context before a step ran. */
|
|
377
|
+
declare class RequiresValidationError extends RunsheetError {
|
|
378
|
+
constructor(message: string);
|
|
379
|
+
}
|
|
380
|
+
/** Schema validation failed on a step's output after it ran. */
|
|
381
|
+
declare class ProvidesValidationError extends RunsheetError {
|
|
382
|
+
constructor(message: string);
|
|
383
|
+
}
|
|
384
|
+
/** Schema validation failed on the pipeline's input arguments. */
|
|
385
|
+
declare class ArgsValidationError extends RunsheetError {
|
|
386
|
+
constructor(message: string);
|
|
387
|
+
}
|
|
388
|
+
/** A `when()` or `choice()` predicate threw an error. */
|
|
389
|
+
declare class PredicateError extends RunsheetError {
|
|
390
|
+
constructor(message: string);
|
|
391
|
+
}
|
|
392
|
+
/** A step exceeded its configured timeout. */
|
|
393
|
+
declare class TimeoutError extends RunsheetError {
|
|
394
|
+
/** The timeout duration in milliseconds that was exceeded. */
|
|
395
|
+
readonly timeoutMs: number;
|
|
396
|
+
constructor(message: string, timeoutMs: number);
|
|
397
|
+
}
|
|
398
|
+
/** A step failed after exhausting all retry attempts. */
|
|
399
|
+
declare class RetryExhaustedError extends RunsheetError {
|
|
400
|
+
/** Total number of attempts (initial + retries). */
|
|
401
|
+
readonly attempts: number;
|
|
402
|
+
constructor(message: string, attempts: number);
|
|
403
|
+
}
|
|
404
|
+
/** Two steps provide the same key (strict mode, detected at build time). */
|
|
405
|
+
declare class StrictOverlapError extends RunsheetError {
|
|
406
|
+
/** The key that is provided by multiple steps. */
|
|
407
|
+
readonly key: string;
|
|
408
|
+
/** The names of the two steps that both provide the key. */
|
|
409
|
+
readonly steps: readonly [string, string];
|
|
410
|
+
constructor(message: string, key: string, steps: readonly [string, string]);
|
|
411
|
+
}
|
|
412
|
+
/** No branch matched in a `choice()` step. */
|
|
413
|
+
declare class ChoiceNoMatchError extends RunsheetError {
|
|
414
|
+
constructor(message: string);
|
|
415
|
+
}
|
|
416
|
+
/** A non-Error value was thrown and caught by the pipeline engine. */
|
|
417
|
+
declare class UnknownError extends RunsheetError {
|
|
418
|
+
/** The original thrown value before stringification. */
|
|
419
|
+
readonly originalValue: unknown;
|
|
420
|
+
constructor(message: string, originalValue: unknown);
|
|
421
|
+
}
|
|
422
|
+
/** One or more rollback handlers failed in a combinator. */
|
|
423
|
+
declare class RollbackError extends RunsheetError {
|
|
424
|
+
constructor(message: string);
|
|
425
|
+
}
|
|
376
426
|
|
|
377
427
|
/**
|
|
378
428
|
* Metadata about the step being executed, passed to middleware.
|
|
@@ -577,6 +627,7 @@ declare function when<Requires extends StepContext, Provides extends StepContext
|
|
|
577
627
|
|
|
578
628
|
/** Ensure a type satisfies StepContext, falling back to StepContext. */
|
|
579
629
|
type AsContext<T> = T extends StepContext ? T : StepContext;
|
|
630
|
+
|
|
580
631
|
/**
|
|
581
632
|
* Run multiple steps concurrently and merge their outputs.
|
|
582
633
|
*
|
|
@@ -612,6 +663,168 @@ type AsContext<T> = T extends StepContext ? T : StepContext;
|
|
|
612
663
|
*/
|
|
613
664
|
declare function parallel<S extends readonly TypedStep[]>(...steps: [...S]): TypedStep<AsContext<UnionToIntersection<ExtractRequires<S[number]>>>, AsContext<UnionToIntersection<ExtractProvides<S[number]>>>>;
|
|
614
665
|
|
|
666
|
+
/** A [predicate, step] tuple used by {@link choice}. */
|
|
667
|
+
type BranchTuple = readonly [(ctx: Readonly<StepContext>) => boolean, TypedStep];
|
|
668
|
+
/** Extract the Requires type from a branch tuple's step. */
|
|
669
|
+
type BranchRequires<T> = T extends readonly [unknown, infer S extends Step] ? ExtractRequires<S> : T extends Step ? ExtractRequires<T> : StepContext;
|
|
670
|
+
/** Extract the Provides type from a branch tuple's step. */
|
|
671
|
+
type BranchProvides<T> = T extends readonly [unknown, infer S extends Step] ? ExtractProvides<S> : T extends Step ? ExtractProvides<T> : StepContext;
|
|
672
|
+
/**
|
|
673
|
+
* Execute the first branch whose predicate returns `true`.
|
|
674
|
+
*
|
|
675
|
+
* Similar to an AWS Step Functions Choice state — predicates are evaluated
|
|
676
|
+
* in order, and the first match wins. Exactly one branch executes. If no
|
|
677
|
+
* predicate matches, the step fails with a `CHOICE_NO_MATCH` error.
|
|
678
|
+
*
|
|
679
|
+
* A bare step (without a predicate tuple) can be passed as the last argument
|
|
680
|
+
* to serve as a default branch — it is equivalent to `[() => true, step]`.
|
|
681
|
+
*
|
|
682
|
+
* All branches should provide the same output shape so that subsequent
|
|
683
|
+
* steps can rely on a consistent context type.
|
|
684
|
+
*
|
|
685
|
+
* @example
|
|
686
|
+
* ```ts
|
|
687
|
+
* const pipeline = buildPipeline({
|
|
688
|
+
* name: 'payment',
|
|
689
|
+
* steps: [
|
|
690
|
+
* validateOrder,
|
|
691
|
+
* choice(
|
|
692
|
+
* [(ctx) => ctx.method === 'card', chargeCard],
|
|
693
|
+
* [(ctx) => ctx.method === 'bank', chargeBankTransfer],
|
|
694
|
+
* chargeDefault, // default
|
|
695
|
+
* ),
|
|
696
|
+
* sendReceipt,
|
|
697
|
+
* ],
|
|
698
|
+
* });
|
|
699
|
+
* ```
|
|
700
|
+
*
|
|
701
|
+
* @param branches - One or more `[predicate, step]` tuples, optionally
|
|
702
|
+
* followed by a bare step as the default.
|
|
703
|
+
* @returns A frozen {@link TypedStep} that executes the first matching branch.
|
|
704
|
+
*/
|
|
705
|
+
declare function choice<B extends readonly BranchTuple[]>(...branches: [...B]): TypedStep<AsContext<UnionToIntersection<BranchRequires<B[number]>>>, AsContext<UnionToIntersection<BranchProvides<B[number]>>>>;
|
|
706
|
+
declare function choice<B extends readonly BranchTuple[], D extends TypedStep>(...args: [...B, D]): TypedStep<AsContext<UnionToIntersection<BranchRequires<B[number]> | ExtractRequires<D>>>, AsContext<UnionToIntersection<BranchProvides<B[number]> | ExtractProvides<D>>>>;
|
|
707
|
+
|
|
708
|
+
/**
|
|
709
|
+
* Iterate over a collection and run a function or step per item, concurrently.
|
|
710
|
+
*
|
|
711
|
+
* Similar to an AWS Step Functions Map state — extracts a collection from
|
|
712
|
+
* the pipeline context, runs the callback for each item via
|
|
713
|
+
* `Promise.allSettled`, and collects results into an array under the
|
|
714
|
+
* given key.
|
|
715
|
+
*
|
|
716
|
+
* **Function form:** `(item, ctx) => result` — items can be any type.
|
|
717
|
+
*
|
|
718
|
+
* **Step form:** each item must be an object whose keys are spread into
|
|
719
|
+
* the pipeline context before the step runs (i.e., the step receives
|
|
720
|
+
* `{ ...ctx, ...item }`). The step's own `requires`/`provides`
|
|
721
|
+
* validation, `retry`, and `timeout` apply per item. On partial failure,
|
|
722
|
+
* succeeded items are rolled back (if the step has a rollback handler).
|
|
723
|
+
*
|
|
724
|
+
* @example
|
|
725
|
+
* ```ts
|
|
726
|
+
* // Function form
|
|
727
|
+
* const pipeline = buildPipeline({
|
|
728
|
+
* name: 'notify',
|
|
729
|
+
* steps: [
|
|
730
|
+
* map('emails', (ctx) => ctx.users, async (user) => {
|
|
731
|
+
* await sendEmail(user.email);
|
|
732
|
+
* return { email: user.email, sentAt: new Date() };
|
|
733
|
+
* }),
|
|
734
|
+
* ],
|
|
735
|
+
* });
|
|
736
|
+
*
|
|
737
|
+
* // Step form
|
|
738
|
+
* const pipeline = buildPipeline({
|
|
739
|
+
* name: 'process',
|
|
740
|
+
* steps: [
|
|
741
|
+
* map('results', (ctx) => ctx.items, processItem),
|
|
742
|
+
* ],
|
|
743
|
+
* });
|
|
744
|
+
* ```
|
|
745
|
+
*
|
|
746
|
+
* @param key - The output key under which results are collected.
|
|
747
|
+
* @param collection - A selector that extracts the collection from context.
|
|
748
|
+
* @param fnOrStep - A per-item function or a step to execute for each item.
|
|
749
|
+
* @returns A frozen {@link TypedStep} that provides `{ [key]: Result[] }`.
|
|
750
|
+
*/
|
|
751
|
+
declare function map<K extends string, Item, Result>(key: K, collection: (ctx: Readonly<StepContext>) => Item[], fn: (item: Item, ctx: Readonly<StepContext>) => Result | Promise<Result>): TypedStep<StepContext, Record<K, Awaited<Result>[]>>;
|
|
752
|
+
declare function map<K extends string, S extends TypedStep>(key: K, collection: (ctx: Readonly<StepContext>) => StepContext[], step: S): TypedStep<StepContext, Record<K, ExtractProvides<S>[]>>;
|
|
753
|
+
|
|
754
|
+
/**
|
|
755
|
+
* Filter a collection from context using a predicate, concurrently.
|
|
756
|
+
*
|
|
757
|
+
* Extracts a collection from the pipeline context, evaluates the
|
|
758
|
+
* predicate for each item via `Promise.allSettled`, and collects
|
|
759
|
+
* items that pass into an array under the given key. Original order
|
|
760
|
+
* is preserved.
|
|
761
|
+
*
|
|
762
|
+
* The predicate can be sync or async. If any predicate throws, the
|
|
763
|
+
* entire step fails — no partial results are returned.
|
|
764
|
+
*
|
|
765
|
+
* There is no rollback (filtering is a pure operation with nothing
|
|
766
|
+
* to undo).
|
|
767
|
+
*
|
|
768
|
+
* @example
|
|
769
|
+
* ```ts
|
|
770
|
+
* const pipeline = buildPipeline({
|
|
771
|
+
* name: 'notify',
|
|
772
|
+
* steps: [
|
|
773
|
+
* filter('eligible', (ctx) => ctx.users, (user) => user.optedIn),
|
|
774
|
+
* map('emails', (ctx) => ctx.eligible, sendEmail),
|
|
775
|
+
* ],
|
|
776
|
+
* });
|
|
777
|
+
*
|
|
778
|
+
* // Async predicate
|
|
779
|
+
* filter('valid', (ctx) => ctx.orders, async (order) => {
|
|
780
|
+
* const inventory = await checkInventory(order.sku);
|
|
781
|
+
* return inventory.available >= order.quantity;
|
|
782
|
+
* });
|
|
783
|
+
* ```
|
|
784
|
+
*
|
|
785
|
+
* @param key - The output key under which filtered results are collected.
|
|
786
|
+
* @param collection - A selector that extracts the collection from context.
|
|
787
|
+
* @param predicate - A per-item predicate. Return `true` to keep, `false` to discard.
|
|
788
|
+
* @returns A frozen {@link TypedStep} that provides `{ [key]: Item[] }`.
|
|
789
|
+
*/
|
|
790
|
+
declare function filter<K extends string, Item>(key: K, collection: (ctx: Readonly<StepContext>) => Item[], predicate: (item: Item, ctx: Readonly<StepContext>) => boolean | Promise<boolean>): TypedStep<StepContext, Record<K, Item[]>>;
|
|
791
|
+
|
|
792
|
+
/**
|
|
793
|
+
* Map each item in a collection to an array, then flatten one level.
|
|
794
|
+
*
|
|
795
|
+
* Extracts a collection from the pipeline context, runs the callback
|
|
796
|
+
* for each item via `Promise.allSettled`, and flattens the per-item
|
|
797
|
+
* arrays into a single array under the given key.
|
|
798
|
+
*
|
|
799
|
+
* The callback can be sync or async. If any callback throws, the
|
|
800
|
+
* entire step fails — no partial results are returned.
|
|
801
|
+
*
|
|
802
|
+
* There is no rollback (pure transformation with nothing to undo).
|
|
803
|
+
*
|
|
804
|
+
* @example
|
|
805
|
+
* ```ts
|
|
806
|
+
* // Expand orders into line items
|
|
807
|
+
* const pipeline = buildPipeline({
|
|
808
|
+
* name: 'process',
|
|
809
|
+
* steps: [
|
|
810
|
+
* flatMap('lineItems', (ctx) => ctx.orders, (order) => order.items),
|
|
811
|
+
* ],
|
|
812
|
+
* });
|
|
813
|
+
*
|
|
814
|
+
* // Async callback
|
|
815
|
+
* flatMap('emails', (ctx) => ctx.teams, async (team) => {
|
|
816
|
+
* const members = await fetchMembers(team.id);
|
|
817
|
+
* return members.map((m) => m.email);
|
|
818
|
+
* });
|
|
819
|
+
* ```
|
|
820
|
+
*
|
|
821
|
+
* @param key - The output key under which flattened results are collected.
|
|
822
|
+
* @param collection - A selector that extracts the collection from context.
|
|
823
|
+
* @param fn - A per-item callback that returns an array (or Promise of array).
|
|
824
|
+
* @returns A frozen {@link TypedStep} that provides `{ [key]: Item[] }`.
|
|
825
|
+
*/
|
|
826
|
+
declare function flatMap<K extends string, Item, Result>(key: K, collection: (ctx: Readonly<StepContext>) => Item[], fn: (item: Item, ctx: Readonly<StepContext>) => Result[] | Promise<Result[]>): TypedStep<StepContext, Record<K, Result[]>>;
|
|
827
|
+
|
|
615
828
|
/**
|
|
616
829
|
* A fluent pipeline builder that progressively narrows the accumulated
|
|
617
830
|
* context type as steps are added.
|
|
@@ -707,4 +920,4 @@ declare function createPipeline<Args extends StepContext>(name: string, argsSche
|
|
|
707
920
|
declare function createPipeline<Args extends StepContext>(name: string, options: PipelineOptions): PipelineBuilder<Args, Args>;
|
|
708
921
|
declare function createPipeline<Args extends StepContext>(name: string, argsSchema: ParserSchema<Args>, options: PipelineOptions): PipelineBuilder<Args, Args>;
|
|
709
922
|
|
|
710
|
-
export { type ConditionalStep, type ExtractProvides, type ExtractRequires, type Pipeline, type PipelineBuilder, type PipelineConfig, type PipelineExecutionMeta, type PipelineFailure, type PipelineResult, type PipelineSuccess, type RetryPolicy, type RollbackFailure, type RollbackReport, RunsheetError, type RunsheetErrorCode, type Step, type StepConfig, type StepContext, type StepExecutor, type StepInfo, type StepMiddleware, type StepOutput, type TypedStep, buildPipeline, createPipeline, defineStep, parallel, when };
|
|
923
|
+
export { ArgsValidationError, ChoiceNoMatchError, type ConditionalStep, type ExtractProvides, type ExtractRequires, type Pipeline, type PipelineBuilder, type PipelineConfig, type PipelineExecutionMeta, type PipelineFailure, type PipelineResult, type PipelineSuccess, PredicateError, ProvidesValidationError, RequiresValidationError, RetryExhaustedError, type RetryPolicy, RollbackError, type RollbackFailure, type RollbackReport, RunsheetError, type RunsheetErrorCode, type Step, type StepConfig, type StepContext, type StepExecutor, type StepInfo, type StepMiddleware, type StepOutput, StrictOverlapError, TimeoutError, type TypedStep, UnknownError, buildPipeline, choice, createPipeline, defineStep, filter, flatMap, map, parallel, when };
|