src/lib/nac/scheduler.ts
Prompt
import type { ThreadCall } from "./models"; export class ScheduleError extends Error { constructor(message: string, public readonly callIds: string[]) { super(message); this.name = "ScheduleError"; } } export function topologicalWaves(calls: ThreadCall[]): ThreadCall[][] { const ids = new Set<string>(); for (const call of calls) { if (ids.has(call.call_id)) throw new ScheduleError(`Duplicate call id: ${call.call_id}`, [call.call_id]); ids.add(call.call_id); } for (const call of calls) for (const dependency of call.depends_on) if (!ids.has(dependency)) throw new ScheduleError(`Unknown dependency ${dependency} in ${call.call_id}`, [call.call_id, dependency]); const completed = new Set<string>(); const waves: ThreadCall[][] = []; while (completed.size < calls.length) { const wave = calls.filter((call) => !completed.has(call.call_id) && call.depends_on.every((dependency) => completed.has(dependency))); if (!wave.length) { const blocked = calls.filter((call) => !completed.has(call.call_id)).map((call) => call.call_id); throw new ScheduleError(`Dependency cycle blocks calls: ${blocked.join(", ")}`, blocked); } const names = new Set<string>(); const serialized: ThreadCall[] = []; for (const call of wave) if (!names.has(call.thread_name)) { names.add(call.thread_name); serialized.push(call); } waves.push(serialized); for (const call of serialized) completed.add(call.call_id); } return waves; } export async function mapConcurrent<T, R>(items: T[], limit: number, fn: (item: T) => Promise<R>): Promise<R[]> { if (!Number.isInteger(limit) || limit < 1) throw new Error("Parallelism must be a positive integer"); const results: R[] = new Array(items.length); let cursor = 0; await Promise.all(Array.from({ length: Math.min(limit, items.length) }, async () => { while (cursor < items.length) { const index = cursor++; results[index] = await fn(items[index]); } })); return results; } - **Type-checking limitation:** Complete verification requires the missing `ThreadCall` definition and compiler settings; no definite syntax errors are visible. - **Conditional TypeScript error:** With `strictNullChecks` and `noUncheckedIndexedAccess`, `items[index]` is `T | undefined`, which cannot be passed to `fn` expecting `T`. - **Failure-handling risk:** `mapConcurrent` rejects immediately when a worker fails, but other workers continue running and starting remaining items. - **Input-mutation risk:** Modifying `items` during execution can skip original items, process appended items, or leave holes in `results`. - **Sparse-array risk:** Sparse `items` arrays cause `fn` to receive `undefined`, despite its parameter being typed as `T`. - **Conditional ES5 compatibility error:** Downleveling `ScheduleError` to ES5 without prototype repair can break `instanceof ScheduleError`. - **Performance limitation:** `topologicalWaves` repeatedly scans calls and dependencies, taking worst-case `O(V(V + E))` time—potentially cubic for dense graphs. - **Strict mode:** no type errors, assuming `ThreadCall` has `call_id: string`, `depends_on: string[]` and `thread_name: string`. - **`noUncheckedIndexedAccess`:** `fn(items[index])` fails because `T | undefined` is not assignable to `T` (TS2345). - **`erasableSyntaxOnly`:** the parameter property `public readonly callIds` is not allowed (TS1294). - **`moduleResolution: node16/nodenext` (ESM):** `"./models"` needs an explicit `.js` extension (TS2835). - **`lib` below ES2015:** `Set`, `Array.from`, `Number.isInteger`, `Promise.all` and `async` are not found. - **Not a compiler error:** `new Array(items.length)` is typed `any[]`, so `any` leaks into `results`. **Type errors (strict, default flags, assuming `ThreadCall = { call_id: string; thread_name: string; depends_on: string[] }`):** none. **Conditional type errors (depend on tsconfig / `ThreadCall` definition):** - `fn(items[index])` — `items[index]` is `T | undefined` under `noUncheckedIndexedAccess` → not assignable to `T`. - `public readonly callIds: string[]` parameter property → TS1294 under `erasableSyntaxOnly`. - `call.depends_on` (for-of and `.every`) → "possibly undefined" if `depends_on` is optional in `ThreadCall`. - `ids.has/add(call.call_id)`, `names.has/add(call.thread_name)`, `completed.has(dependency)`, `new ScheduleError(…, [call.call_id, dependency])` → fail if those fields aren't plain `string`. - `Set`, `Number.isInteger`, `Array.from`, `Promise`, `async` → require `lib`/`target` ≥ ES2015. **Non-type (runtime/logic) issues:** - `mapConcurrent`: a single `fn` rejection rejects `Promise.all` while remaining workers keep running; completed results are discarded. - `ScheduleError`: `instanceof` breaks on ES5 target (no `Object.setPrototypeOf(this, ScheduleError.prototype)`). - Cycle error's `blocked` list includes all unfinished calls, not only the cycle members. **TypeScript Type / Compiler Errors:** 1. **`TS2307` (Standalone compilation):** `Cannot find module './models' or its corresponding type declarations.` (`import type { ThreadCall } from "./models"`) 2. **`TS2345` (With `noUncheckedIndexedAccess: true`):** `Argument of type 'T | undefined' is not assignable to parameter of type 'T'.` at `fn(items[index])` because indexed access on `items: T[]` resolves to `T | undefined`. 3. **`TS1294` (With `erasableSyntaxOnly: true`):** Parameter property `public readonly callIds: string[]` in the `ScheduleError` constructor is disallowed. **Runtime / Logic Errors Thrown by the Code:** 1. **`ScheduleError` (Duplicate ID):** ``Duplicate call id: ${call.call_id}`` — thrown when two calls share the same `call_id`. 2. **`ScheduleError` (Missing Dependency):** ``Unknown dependency ${dependency} in ${call.call_id}`` — thrown when a `depends_on` entry does not match any known `call_id`. 3. **`ScheduleError` (Dependency Cycle):** ``Dependency cycle blocks calls: ${blocked.join(", ")}`` — thrown when remaining uncompleted calls cannot progress due to circular dependencies. 4. **`Error` (Invalid Concurrency Limit):** `"Parallelism must be a positive integer"` — thrown in `mapConcurrent` when `limit` is `< 1`, `NaN`, `Infinity`, or a non-integer. - `ScheduleError("Duplicate call id: ...")` - `ScheduleError("Unknown dependency ... in ...")` - `ScheduleError("Dependency cycle blocks calls: ...")` - `Error("Parallelism must be a positive integer")` - Propagated error/rejection from `fn` in `mapConcurrent` - Possible TypeScript error with `noUncheckedIndexedAccess`: `items[index]` is `T | undefined`, not `T` Send back the complete code with all the fixes. Fix each of the listed errors one by one, making sure to actually correct them so that there are 0 errors remaining. Keep the original imports, since the files exist. Write out every single character; do not abbreviate anything. Fix every error. There must be exactly one file. Do not write anything else; just output the complete code, and it must not contain any comments. Never, under any circumstances, use simplified, substitute, dummy, simulated, or fake code. Write the entire file as complete, unabridged, production-ready code in a single code block. It must be 100% error-free, a complete, error-free file, and must be submitted as a downloadable file. These requirements are mandatory and must be strictly adhered to. If no list of errors is provided, you must find all the errors and fix them. If there were comments in the original code, delete them. And most importantly: YOU MUST NEVER SIMPLIFY!
Response not available
Response not available