@mondaydotcomorg/atp-compiler
Version:
Production-ready compiler for transforming async iteration patterns into resumable operations with checkpoint-based state management
179 lines • 6.71 kB
JavaScript
import { getCheckpointManager } from './checkpoint-manager.js';
import { InfiniteLoopDetectionError } from './errors.js';
const MAX_ITERATIONS = 1000000;
export async function resumableMap(items, callback, mapId) {
const checkpointManager = getCheckpointManager();
const checkpoint = await checkpointManager.load(mapId);
const startIndex = checkpoint?.currentIndex || 0;
const results = checkpoint?.results || [];
for (let i = startIndex; i < items.length; i++) {
if (i > MAX_ITERATIONS) {
throw new InfiniteLoopDetectionError(mapId, i);
}
results[i] = await callback(items[i], i, items);
const newCheckpoint = {
loopId: mapId,
currentIndex: i + 1,
results: results,
timestamp: Date.now(),
};
await checkpointManager.save(newCheckpoint);
}
await checkpointManager.clear(mapId);
return results;
}
export async function resumableForEach(items, callback, forEachId) {
const checkpointManager = getCheckpointManager();
const checkpoint = await checkpointManager.load(forEachId);
const startIndex = checkpoint?.currentIndex || 0;
for (let i = startIndex; i < items.length; i++) {
if (i > MAX_ITERATIONS) {
throw new InfiniteLoopDetectionError(forEachId, i);
}
await callback(items[i], i, items);
const newCheckpoint = {
loopId: forEachId,
currentIndex: i + 1,
timestamp: Date.now(),
};
await checkpointManager.save(newCheckpoint);
}
await checkpointManager.clear(forEachId);
}
export async function resumableFilter(items, callback, filterId) {
const checkpointManager = getCheckpointManager();
const checkpoint = await checkpointManager.load(filterId);
const startIndex = checkpoint?.currentIndex || 0;
const results = checkpoint?.results || [];
for (let i = startIndex; i < items.length; i++) {
if (i > MAX_ITERATIONS) {
throw new InfiniteLoopDetectionError(filterId, i);
}
const passed = await callback(items[i], i, items);
if (passed) {
results.push(items[i]);
}
const newCheckpoint = {
loopId: filterId,
currentIndex: i + 1,
results: results,
timestamp: Date.now(),
};
await checkpointManager.save(newCheckpoint);
}
await checkpointManager.clear(filterId);
return results;
}
export async function resumableReduce(items, callback, initialValue, reduceId) {
const checkpointManager = getCheckpointManager();
const checkpoint = await checkpointManager.load(reduceId);
const startIndex = checkpoint?.currentIndex || 0;
let accumulator = checkpoint?.accumulator ?? initialValue;
for (let i = startIndex; i < items.length; i++) {
if (i > MAX_ITERATIONS) {
throw new InfiniteLoopDetectionError(reduceId, i);
}
accumulator = await callback(accumulator, items[i], i, items);
const newCheckpoint = {
loopId: reduceId,
currentIndex: i + 1,
accumulator: accumulator,
timestamp: Date.now(),
};
await checkpointManager.save(newCheckpoint);
}
await checkpointManager.clear(reduceId);
return accumulator;
}
export async function resumableFind(items, callback, findId) {
const checkpointManager = getCheckpointManager();
const checkpoint = await checkpointManager.load(findId);
const startIndex = checkpoint?.currentIndex || 0;
for (let i = startIndex; i < items.length; i++) {
if (i > MAX_ITERATIONS) {
throw new InfiniteLoopDetectionError(findId, i);
}
const found = await callback(items[i], i, items);
if (found) {
await checkpointManager.clear(findId);
return items[i];
}
const newCheckpoint = {
loopId: findId,
currentIndex: i + 1,
timestamp: Date.now(),
};
await checkpointManager.save(newCheckpoint);
}
await checkpointManager.clear(findId);
return undefined;
}
export async function resumableSome(items, callback, someId) {
const checkpointManager = getCheckpointManager();
const checkpoint = await checkpointManager.load(someId);
const startIndex = checkpoint?.currentIndex || 0;
for (let i = startIndex; i < items.length; i++) {
if (i > MAX_ITERATIONS) {
throw new InfiniteLoopDetectionError(someId, i);
}
const result = await callback(items[i], i, items);
if (result) {
await checkpointManager.clear(someId);
return true;
}
const newCheckpoint = {
loopId: someId,
currentIndex: i + 1,
timestamp: Date.now(),
};
await checkpointManager.save(newCheckpoint);
}
await checkpointManager.clear(someId);
return false;
}
export async function resumableEvery(items, callback, everyId) {
const checkpointManager = getCheckpointManager();
const checkpoint = await checkpointManager.load(everyId);
const startIndex = checkpoint?.currentIndex || 0;
for (let i = startIndex; i < items.length; i++) {
if (i > MAX_ITERATIONS) {
throw new InfiniteLoopDetectionError(everyId, i);
}
const result = await callback(items[i], i, items);
if (!result) {
await checkpointManager.clear(everyId);
return false;
}
const newCheckpoint = {
loopId: everyId,
currentIndex: i + 1,
timestamp: Date.now(),
};
await checkpointManager.save(newCheckpoint);
}
await checkpointManager.clear(everyId);
return true;
}
export async function resumableFlatMap(items, callback, flatMapId) {
const checkpointManager = getCheckpointManager();
const checkpoint = await checkpointManager.load(flatMapId);
const startIndex = checkpoint?.currentIndex || 0;
const results = checkpoint?.results || [];
for (let i = startIndex; i < items.length; i++) {
if (i > MAX_ITERATIONS) {
throw new InfiniteLoopDetectionError(flatMapId, i);
}
const mapped = await callback(items[i], i, items);
results.push(...mapped);
const newCheckpoint = {
loopId: flatMapId,
currentIndex: i + 1,
results: results,
timestamp: Date.now(),
};
await checkpointManager.save(newCheckpoint);
}
await checkpointManager.clear(flatMapId);
return results;
}
//# sourceMappingURL=resumable-arrays.js.map