@classytic/streamline 1.0.0 → 2.0.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 CHANGED
@@ -41,7 +41,7 @@ draft → running → waiting ↔ running → done
41
41
  ## Installation
42
42
 
43
43
  ```bash
44
- npm install @classytic/streamline mongoose
44
+ npm install @classytic/streamline @classytic/mongokit mongoose
45
45
  ```
46
46
 
47
47
  ## Quick Start
@@ -140,35 +140,40 @@ const workflow = createWorkflow('parallel-fetch', {
140
140
  });
141
141
  ```
142
142
 
143
- ### 4. Conditional Steps
143
+ ### 4. Per-Step Timeout, Retries & Conditions
144
144
 
145
- Use conditional execution in your handlers:
145
+ Mix plain handlers with `StepConfig` objects for fine-grained control. `TContext` infers everywhere — zero annotations needed:
146
146
 
147
147
  ```typescript
148
- const workflow = createWorkflow('conditional-flow', {
148
+ import { createWorkflow } from '@classytic/streamline';
149
+
150
+ const pipeline = createWorkflow<{ shouldDeploy: boolean }>('ci-pipeline', {
149
151
  steps: {
150
- check: async (ctx) => {
151
- return { tier: ctx.context.tier };
152
+ // Plain handler zero ceremony
153
+ clone: async (ctx) => {
154
+ return { repo: 'cloned' };
152
155
  },
153
- premiumFeature: async (ctx) => {
154
- // Only runs for premium users
155
- if (ctx.context.tier !== 'premium') {
156
- return { skipped: true };
157
- }
158
- return { premium: true };
156
+
157
+ // StepConfig per-step timeout and retries
158
+ build: {
159
+ handler: async (ctx) => {
160
+ return { artifact: 'build.tar.gz' };
161
+ },
162
+ timeout: 120_000, // 2 min timeout (this step only)
163
+ retries: 5, // 5 attempts (this step only)
164
+ },
165
+
166
+ // StepConfig — conditional execution
167
+ deploy: {
168
+ handler: async (ctx) => {
169
+ return { deployed: true };
170
+ },
171
+ timeout: 300_000,
172
+ skipIf: (ctx) => !ctx.shouldDeploy, // ctx is typed as your TContext
159
173
  },
160
- expressShipping: async (ctx) => {
161
- // Conditional logic
162
- if (ctx.context.priority === 'express') {
163
- return { shipping: 'express' };
164
- }
165
- return { shipping: 'standard' };
166
- }
167
174
  },
168
- context: (input: any) => ({
169
- tier: input.tier,
170
- priority: input.priority
171
- })
175
+ context: (input: any) => ({ shouldDeploy: input.deploy }),
176
+ defaults: { retries: 3, timeout: 30_000 }, // Fallback for plain handlers
172
177
  });
173
178
  ```
174
179
 
@@ -710,6 +715,44 @@ See [TESTING.md](./TESTING.md) for testing guide.
710
715
  - **Concurrency**: Atomic claiming prevents duplicate execution
711
716
  - **Memory**: Auto garbage collection via WeakRef
712
717
 
718
+ ## Advanced: Scheduler Concurrency Limit
719
+
720
+ Prevent overwhelming API rate limits or memory when each step runs a long-running agent:
721
+
722
+ ```typescript
723
+ const workflow = createWorkflow('agent-pipeline', {
724
+ steps: { ... },
725
+ });
726
+
727
+ // Limit to 10 workflows executing simultaneously
728
+ workflow.engine.configure({
729
+ scheduler: { maxConcurrentExecutions: 10 },
730
+ });
731
+ ```
732
+
733
+ When all slots are full, the scheduler skips the poll cycle — workflows wait in `running` queue until a slot frees up. Default is `Infinity` (no limit).
734
+
735
+ ## Advanced: Type Exports
736
+
737
+ All public types are exported — no `ReturnType<>` workarounds needed:
738
+
739
+ ```typescript
740
+ import {
741
+ createWorkflow,
742
+ type Workflow, // The workflow instance type
743
+ type WorkflowConfig, // The config object type
744
+ type StepConfig, // Per-step config type
745
+ type WaitForOptions, // waitFor() options
746
+ type WorkflowRun, // The run document type
747
+ } from '@classytic/streamline';
748
+
749
+ // Export your workflows without TS4023
750
+ export const myWorkflow: Workflow<MyCtx, MyInput> = createWorkflow('my', { ... });
751
+
752
+ // Type config objects separately
753
+ const config: WorkflowConfig<MyCtx> = { steps: { ... } };
754
+ ```
755
+
713
756
  ## Advanced: Dependency Injection
714
757
 
715
758
  For testing or running multiple isolated engines, use the container directly: