UNPKG

@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
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