@mondaydotcomorg/atp-compiler
Production-ready compiler for transforming async iteration patterns into resumable operations with checkpoint-based state management.
Overview
The ATP compiler automatically transforms async loops and array methods into resumable operations, enabling true pause/resume from any iteration point. Includes batch parallel execution optimization for 100x speedups on concurrent operations.
Installation
npm install @mondaydotcomorg/atp-compiler
Architecture
graph TB
Compiler[ATPCompiler] --> Detect[Pattern Detection]
Compiler --> Transform[Code Transformation]
Detect --> ForLoop[for...of with await]
Detect --> ArrayMethods[map/filter/reduce]
Detect --> PromiseAll[Promise.all batch]
Transform --> Sequential[Sequential + Checkpoints]
Transform --> Parallel[Batch Parallel]
Sequential --> State[Checkpoint State]
State --> Cache[Cache Provider]
Parallel --> Concurrent[Concurrent Execution]
Features
- Automatic transformation of async loops and array methods
- Batch parallel execution for concurrent LLM/approval requests (up to 100x faster)
- Checkpoint-based state for true pause/resume from any iteration
- Zero syntax changes - works with standard JavaScript/TypeScript
- Production-ready with extensive testing and error handling
Quick Start
import { ATPCompiler, initializeRuntime } from '@mondaydotcomorg/atp-compiler';
import { cacheProvider } from '@mondaydotcomorg/atp-protocol';
initializeRuntime({
executionId: 'exec-123',
cache: cacheProvider,
});
const compiler = new ATPCompiler({
enableBatchParallel: true,
});
const userCode = `
const items = [1, 2, 3, 4, 5];
const results = [];
for (const item of items) {
const response = await atp.llm.call({ prompt: \`Process \${item}\` });
results.push(response);
}
return results;
`;
const result = compiler.transform(userCode);
Batch Optimization
The compiler automatically detects simple patterns and optimizes for batch parallel execution - achieving up to 100x speedup!
Automatic Batching
const results = await items.map(async (item) => {
return await atp.llm.call({ prompt: item });
});
Complex Patterns = Sequential
const results = await items.map(async (item) => {
if (item.priority > 5) {
return await atp.llm.call({ prompt: item });
}
});
Supported Patterns
For Loops
for (const item of items) {
await atp.llm.call({ prompt: item });
}
Array Methods
const results = await items.map(async (item) => {
return await atp.llm.call({ prompt: item });
});
Batch Parallel
const results = await Promise.all([
atp.llm.call({ prompt: 'Q1' }),
atp.llm.call({ prompt: 'Q2' }),
atp.llm.call({ prompt: 'Q3' }),
]);
API Reference
ATPCompiler
const compiler = new ATPCompiler({
enableBatchParallel: true,
maxLoopNesting: 10,
debugMode: false,
});
const detection = compiler.detect(code);
const result = compiler.transform(code);
Runtime Initialization
import { initializeRuntime } from '@mondaydotcomorg/atp-compiler';
initializeRuntime({
executionId: 'unique-exec-id',
cache: cacheProvider,
checkpointPrefix: 'checkpoint',
});
Checkpoint System
The compiler uses checkpoints to save loop state:
- Every iteration is checkpointed
- State includes: current index, results, accumulator
- TTL: 1 hour (configurable via cache provider)
- Storage: Uses ATP cache provider (Redis recommended)
interface Checkpoint {
index: number;
results: unknown[];
accumulator?: unknown;
timestamp: number;
}
Batch Parallel Execution
When enabled, direct pausable calls in Promise.all execute concurrently:
await Promise.all([atp.llm.call({ prompt: 'Q1' }), atp.llm.call({ prompt: 'Q2' })]);
await Promise.all(
items.map(async (item) => {
const step1 = await atp.llm.call({ prompt: item });
return await process(step1);
})
);
Performance Comparison
| Sequential loop (100 items) | 200s | 200s + checkpointing | ~200s |
| Batch parallel (100 items) | 200s | 2s | 100x |
| Promise.all (10 items) | 20s | 2s | 10x |
Error Handling
import {
isBatchPauseError,
isCheckpointError,
isTransformationError,
} from '@mondaydotcomorg/atp-compiler';
try {
const result = compiler.transform(code);
} catch (error) {
if (isTransformationError(error)) {
console.error('Transformation failed:', error.message);
console.error('Pattern:', error.pattern);
console.error('Location:', error.location);
}
}
Limitations
Not supported:
- Recursive functions with await
for await...of with async iterators
- Dynamic code generation (eval, new Function)
- Non-serializable objects in checkpoints
Supported:
- All standard array methods with async callbacks
- Nested loops up to 10 levels
- Try/catch around iterations
- Break/continue statements
- Early returns
Integration with ATP Server
import { ATPCompiler, initializeRuntime } from '@mondaydotcomorg/atp-compiler';
const compiler = new ATPCompiler();
if (cacheProvider) {
initializeRuntime({
executionId,
cache: cacheProvider,
});
const detection = compiler.detect(code);
if (detection.needsTransform) {
const transformed = compiler.transform(code);
codeToExecute = transformed.code;
}
}
Example: Transform and Execute
import { ATPCompiler, initializeRuntime } from '@mondaydotcomorg/atp-compiler';
import { RedisCache } from '@mondaydotcomorg/atp-providers';
import Redis from 'ioredis';
const redis = new Redis();
const cache = new RedisCache({ redis });
const compiler = new ATPCompiler({
enableBatchParallel: true,
});
const code = `
const urls = [
'https://api.example.com/users/1',
'https://api.example.com/users/2',
'https://api.example.com/users/3',
];
const users = await Promise.all(
urls.map(url => atp.llm.call({ prompt: 'Summarize: ' + url }))
);
return users;
`;
initializeRuntime({
executionId: 'exec-456',
cache,
});
const result = compiler.transform(code);
const executionResult = await executor.execute(result.code);
Transformation Examples
Before (Sequential)
const items = ['a', 'b', 'c'];
const results = [];
for (const item of items) {
const response = await atp.llm.call({ prompt: item });
results.push(response);
}
After (Resumable)
const items = ['a', 'b', 'c'];
const results = [];
const checkpointKey = 'checkpoint:exec-123:loop-1';
let startIndex = 0;
const checkpoint = await cache.get(checkpointKey);
if (checkpoint) {
startIndex = checkpoint.index;
results.push(...checkpoint.results);
}
for (let i = startIndex; i < items.length; i++) {
const item = items[i];
const response = await atp.llm.call({ prompt: item });
results.push(response);
await cache.set(checkpointKey, { index: i + 1, results }, 3600);
}
Testing
npm test
npm run test:watch
npm run test:coverage
TypeScript Support
Full TypeScript definitions with strict typing.
License
MIT