synai-simulator 0.1.0 → 0.1.1

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/dist/index.d.ts CHANGED
@@ -28,6 +28,7 @@ type Task = {
28
28
  failureType?: FailureType;
29
29
  maxQueueTime?: number;
30
30
  status: TaskStatus;
31
+ finishedAt?: number;
31
32
  };
32
33
 
33
34
  type Worker = {
package/dist/index.js CHANGED
@@ -110,6 +110,7 @@ function schedule(state2, dt, rng2) {
110
110
  t.status = "failed";
111
111
  t.failureType = "starvation";
112
112
  t.failureReason = "Starvation: task waited too long in queue under pressure";
113
+ t.finishedAt = now;
113
114
  }
114
115
  }
115
116
  const queued = state2.tasks.filter((t) => t.status === "queued");
@@ -118,6 +119,7 @@ function schedule(state2, dt, rng2) {
118
119
  worst.status = "failed";
119
120
  worst.failureType = "load_shed";
120
121
  worst.failureReason = "Load shed: system pressure exceeded safe threshold";
122
+ worst.finishedAt = now;
121
123
  }
122
124
  const queuedWithCost = state2.tasks.filter((t) => t.status === "queued").map((t) => ({ t, cost: computeTaskCost(t, state2).total }));
123
125
  let sortedQueued;
@@ -169,6 +171,7 @@ function schedule(state2, dt, rng2) {
169
171
  t.status = "failed";
170
172
  t.failureType = "timeout";
171
173
  t.failureReason = "Deadline exceeded under sustained pressure";
174
+ t.finishedAt = now;
172
175
  continue;
173
176
  }
174
177
  }
@@ -180,10 +183,12 @@ function schedule(state2, dt, rng2) {
180
183
  t.status = "failed";
181
184
  t.failureType = "pressure";
182
185
  t.failureReason = `Execution failure (\u03BB=${lambda.toFixed(3)})`;
186
+ t.finishedAt = now;
183
187
  continue;
184
188
  }
185
189
  if (t.progress >= 1) {
186
190
  t.status = "completed";
191
+ t.finishedAt = now;
187
192
  }
188
193
  if (rng2() < 0.15) {
189
194
  t.phase = t.phase === "cpu" ? "io" : "cpu";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/engine/policy.ts","../src/engine/random.ts","../src/engine/metrics.ts","../src/engine/cost.ts","../src/engine/execution.ts","../src/engine/scheduler.ts","../src/engine/tick.ts","../src/worker/simulator.worker.ts"],"sourcesContent":["export type PolicyName = \"FAIRNESS\" | \"BALANCED\" | \"THROUGHPUT\";\r\n\r\nexport type Policy = {\r\n starvationWeight: number;\r\n latenessWeight: number;\r\n failureWeight: number;\r\n instabilityWeight: number;\r\n};\r\n\r\nexport const POLICIES: Record<PolicyName, Policy> = {\r\n FAIRNESS: {\r\n starvationWeight: 2,\r\n latenessWeight: 0.8,\r\n failureWeight: 1,\r\n instabilityWeight: 0.5,\r\n },\r\n BALANCED: {\r\n starvationWeight: 0.5,\r\n latenessWeight: 1,\r\n failureWeight: 2,\r\n instabilityWeight: 1,\r\n },\r\n THROUGHPUT: {\r\n starvationWeight: 0.1,\r\n latenessWeight: 1.5,\r\n failureWeight: 3,\r\n instabilityWeight: 2,\r\n },\r\n};\r\n","export type RNG = () => number;\r\n\r\nexport function createRNG(seed: number): RNG {\r\n let t = seed >>> 0;\r\n\r\n return function () {\r\n t += 0x6d2b79f5;\r\n let r = Math.imul(t ^ (t >>> 15), 1 | t);\r\n r ^= r + Math.imul(r ^ (r >>> 7), 61 | r);\r\n return ((r ^ (r >>> 14)) >>> 0) / 4294967296;\r\n };\r\n}\r\n","import { SystemState } from \"../core/state\";\r\n\r\nexport function computeMetrics(state: SystemState): SystemState {\r\n let usedCPU = 0;\r\n let usedRAM = 0;\r\n\r\n for (const task of state.tasks) {\r\n if (task.status === \"running\") {\r\n usedCPU += task.execution.cpuCurve.base;\r\n usedRAM += task.execution.ramCurve.base;\r\n }\r\n }\r\n\r\n const cpuPressure = usedCPU / state.resources.totalCPU;\r\n const ramPressure = usedRAM / state.resources.totalRAM;\r\n const pressure = Math.max(cpuPressure, ramPressure);\r\n\r\n const queueLength = state.tasks.filter((t) => t.status === \"queued\").length;\r\n\r\n const failed = state.tasks.filter((t) => t.status === \"failed\").length;\r\n\r\n // 🔥 System Stability Index (0–100)\r\n const pressurePenalty = Math.min(pressure * 50, 60);\r\n const queuePenalty = Math.min(queueLength * 3, 25);\r\n const failurePenalty = Math.min(failed * 5, 40);\r\n\r\n const stabilityIndex = Math.max(\r\n 0,\r\n Math.round(100 - pressurePenalty - queuePenalty - failurePenalty)\r\n );\r\n\r\n state.metrics = {\r\n ...state.metrics,\r\n cpuPressure,\r\n ramPressure,\r\n pressure,\r\n queueLength,\r\n completed: state.tasks.filter((t) => t.status === \"completed\").length,\r\n failed,\r\n stabilityIndex,\r\n };\r\n\r\n return state;\r\n}\r\n","import { Task } from \"../core/task\";\r\nimport { SystemState } from \"../core/state\";\r\nimport { POLICIES } from \"./policy\";\r\n\r\nexport type CostBreakdown = {\r\n starvation: number;\r\n lateness: number;\r\n failureRisk: number;\r\n instability: number;\r\n total: number;\r\n};\r\n\r\nexport function computeTaskCost(task: Task, state: SystemState): CostBreakdown {\r\n const policy = POLICIES[state.policy];\r\n const now = state.time;\r\n const pressure = state.metrics.pressure;\r\n\r\n // --- Starvation ---\r\n const waitingTime = task.startedAt === undefined ? now - task.createdAt : 0;\r\n\r\n const starvation = waitingTime * policy.starvationWeight;\r\n\r\n // --- Lateness ---\r\n const latenessTime = Math.max(0, now - task.deadline);\r\n\r\n const lateness = latenessTime * policy.latenessWeight;\r\n\r\n // --- Failure Risk (expected loss) ---\r\n const failureRisk = task.failureProbability * pressure * policy.failureWeight;\r\n\r\n // --- System Instability ---\r\n const instability = pressure * pressure * policy.instabilityWeight;\r\n\r\n const total = starvation + lateness + failureRisk + instability;\r\n\r\n return {\r\n starvation,\r\n lateness,\r\n failureRisk,\r\n instability,\r\n total,\r\n };\r\n}\r\n","import { ResourceCurve } from \"../core/task\";\r\nimport { RNG } from \"./random\";\r\n\r\nexport function sampleUsage(curve: ResourceCurve, rng: RNG): number {\r\n const spread = curve.peak - curve.base;\r\n\r\n // centered noise in [-0.5, 0.5]\r\n const noise = (rng() - 0.5) * 2;\r\n\r\n const usage = curve.base + spread * curve.variance * noise;\r\n\r\n return Math.max(0, usage);\r\n}\r\n\r\nexport function slowdownFactor(pressure: number): number {\r\n return 1 + pressure * pressure;\r\n}\r\n","import { SystemState } from \"../core/state\";\r\nimport { computeTaskCost } from \"./cost\";\r\nimport { slowdownFactor } from \"./execution\";\r\nimport { RNG } from \"./random\";\r\nimport { sampleUsage } from \"./execution\";\r\n\r\nconst MAX_PRESSURE = 1.2;\r\n\r\nfunction phaseFailureMultiplier(phase: \"cpu\" | \"io\") {\r\n return phase === \"io\" ? 1.6 : 1.0;\r\n}\r\n\r\nexport function schedule(\r\n state: SystemState,\r\n dt: number,\r\n rng: RNG\r\n): SystemState {\r\n const now = state.time;\r\n\r\n /* =========================================================\r\n 1. STARVATION FAILURE (queued too long, under pressure)\r\n ========================================================= */\r\n\r\n for (const t of state.tasks) {\r\n if (\r\n t.status === \"queued\" &&\r\n t.maxQueueTime !== undefined &&\r\n now - t.createdAt > t.maxQueueTime &&\r\n state.metrics.pressure > 1\r\n ) {\r\n t.status = \"failed\";\r\n t.failureType = \"starvation\";\r\n t.failureReason =\r\n \"Starvation: task waited too long in queue under pressure\";\r\n }\r\n }\r\n\r\n const queued = state.tasks.filter((t) => t.status === \"queued\");\r\n\r\n /* =========================================================\r\n 2. LOAD SHEDDING (system protection)\r\n ========================================================= */\r\n\r\n if (state.metrics.pressure > MAX_PRESSURE && queued.length > 0) {\r\n const worst = queued\r\n .map((t) => ({ t, cost: computeTaskCost(t, state).total }))\r\n .sort((a, b) => b.cost - a.cost)[0].t;\r\n\r\n worst.status = \"failed\";\r\n worst.failureType = \"load_shed\";\r\n worst.failureReason = \"Load shed: system pressure exceeded safe threshold\";\r\n }\r\n\r\n /* =========================================================\r\n 3. ADMISSION CONTROL (concurrency-limited)\r\n ========================================================= */\r\n\r\n const queuedWithCost = state.tasks\r\n .filter((t) => t.status === \"queued\")\r\n .map((t) => ({ t, cost: computeTaskCost(t, state).total }));\r\n\r\n let sortedQueued;\r\n\r\n switch (state.policy) {\r\n case \"THROUGHPUT\":\r\n // favor cheap tasks → maximize completions\r\n sortedQueued = queuedWithCost.sort((a, b) => a.cost - b.cost);\r\n break;\r\n\r\n case \"FAIRNESS\":\r\n // favor oldest tasks\r\n sortedQueued = queuedWithCost.sort(\r\n (a, b) => a.t.createdAt - b.t.createdAt\r\n );\r\n break;\r\n\r\n case \"BALANCED\":\r\n default:\r\n // mix age + cost\r\n sortedQueued = queuedWithCost.sort(\r\n (a, b) =>\r\n 0.5 * (a.cost - b.cost) + 0.5 * (a.t.createdAt - b.t.createdAt)\r\n );\r\n }\r\n\r\n let runningCount = state.tasks.filter((t) => t.status === \"running\").length;\r\n\r\n for (const { t } of sortedQueued) {\r\n if (runningCount >= state.config.maxConcurrentTasks) break;\r\n\r\n t.status = \"running\";\r\n t.startedAt = now;\r\n t.expectedEndAt = now + t.execution.meanDuration;\r\n\r\n t.currentRAM = sampleUsage(t.execution.ramCurve, rng);\r\n\r\n runningCount++;\r\n }\r\n\r\n /* =========================================================\r\n 4. EXECUTE RUNNING TASKS\r\n ========================================================= */\r\n\r\n const running = state.tasks.filter((t) => t.status === \"running\");\r\n\r\n /* ---------- CPU SHARING ---------- */\r\n const cpuTasks = running.filter((t) => t.phase === \"cpu\");\r\n const cpuPerTask =\r\n cpuTasks.length > 0 ? state.resources.totalCPU / cpuTasks.length : 0;\r\n\r\n /* ---------- RAM ACCUMULATION ---------- */\r\n let totalUsedRAM = 0;\r\n for (const t of running) {\r\n if (t.currentRAM !== undefined) {\r\n totalUsedRAM += t.currentRAM;\r\n }\r\n }\r\n\r\n state.metrics.ramPressure = totalUsedRAM / state.resources.totalRAM;\r\n\r\n /* ---------- EXECUTION LOOP ---------- */\r\n for (const t of running) {\r\n const cpuSlow = slowdownFactor(state.metrics.cpuPressure);\r\n\r\n if (t.phase === \"cpu\") {\r\n t.progress +=\r\n ((cpuPerTask / state.resources.totalCPU) *\r\n (dt / t.execution.meanDuration)) /\r\n cpuSlow;\r\n } else {\r\n const ramSlow = 1 + Math.max(0, state.metrics.ramPressure - 1);\r\n\r\n t.progress += (0.3 * dt) / t.execution.meanDuration / ramSlow;\r\n }\r\n\r\n /* ---------- TIMEOUT FAILURE ---------- */\r\n if (t.deadline !== undefined && t.startedAt !== undefined) {\r\n const effectiveDeadline =\r\n t.deadline * Math.max(1, state.metrics.pressure);\r\n\r\n if (now - t.startedAt > effectiveDeadline && state.metrics.pressure > 1) {\r\n t.status = \"failed\";\r\n t.failureType = \"timeout\";\r\n t.failureReason = \"Deadline exceeded under sustained pressure\";\r\n continue;\r\n }\r\n }\r\n\r\n /* ---------- PRESSURE-CORRELATED FAILURE ---------- */\r\n const runTime = t.startedAt !== undefined ? now - t.startedAt : 0;\r\n\r\n const fatigueMultiplier = 1 + Math.min(runTime / 10, 1);\r\n\r\n const lambda =\r\n t.failureProbability *\r\n phaseFailureMultiplier(t.phase) *\r\n fatigueMultiplier *\r\n state.metrics.pressure;\r\n\r\n const perTickRisk = 1 - Math.exp(-lambda * dt);\r\n\r\n if (rng() < perTickRisk) {\r\n t.status = \"failed\";\r\n t.failureType = \"pressure\";\r\n t.failureReason = `Execution failure (λ=${lambda.toFixed(3)})`;\r\n continue;\r\n }\r\n\r\n /* ---------- COMPLETION ---------- */\r\n if (t.progress >= 1) {\r\n t.status = \"completed\";\r\n }\r\n\r\n /* ---------- ASYNC ILLUSION ---------- */\r\n if (rng() < 0.15) {\r\n t.phase = t.phase === \"cpu\" ? \"io\" : \"cpu\";\r\n }\r\n }\r\n\r\n return state;\r\n}\r\n","import { SystemState } from \"../core/state\";\r\nimport { computeMetrics } from \"./metrics\";\r\nimport { schedule } from \"./scheduler\";\r\nimport { RNG } from \"./random\";\r\n\r\nexport function tick(state: SystemState, dt: number, rng: RNG): SystemState {\r\n let next = { ...state, time: state.time + dt };\r\n\r\n next = computeMetrics(next);\r\n next = schedule(next, dt, rng);\r\n next = computeMetrics(next);\r\n\r\n return next;\r\n}\r\n","/// <reference lib=\"webworker\" />\r\nconsole.log(\"🔥 WORKER FILE EXECUTED\");\r\nimport { tick } from \"../engine/tick\";\r\nimport { SystemState } from \"../core/state\";\r\nimport { Task } from \"../core/task\";\r\nimport { PolicyName } from \"../engine/policy\";\r\nimport { SystemResources } from \"../core/resources\";\r\nimport { createRNG } from \"../engine/random\";\r\nlet currentSeed: number = 1;\r\nlet rng = createRNG(currentSeed);\r\n\r\nlet state: SystemState | null = null;\r\nlet interval: ReturnType<typeof setInterval> | null = null;\r\n\r\nconst TICK_MS = 100;\r\nlet sustainedPressureTicks = 0;\r\nconst COLLAPSE_PRESSURE = 1.5;\r\nconst COLLAPSE_TICKS = 10;\r\n\r\nlet eventLog: Array<{\r\n time: number;\r\n message: any;\r\n}> = [];\r\n\r\nself.onmessage = (event: MessageEvent) => {\r\n const msg = event.data;\r\n // Log user actions (but NOT INIT or STATE)\r\n if (state && ![\"STATE\", \"INIT\"].includes(msg.type)) {\r\n eventLog.push({\r\n time: state.time,\r\n message: msg,\r\n });\r\n }\r\n switch (msg.type) {\r\n case \"INIT\": {\r\n state = structuredClone(msg.payload.state);\r\n initialSnapshot = structuredClone(msg.payload.state);\r\n currentSeed = msg.payload.seed ?? 1;\r\n rng = createRNG(currentSeed);\r\n eventLog = [];\r\n sustainedPressureTicks = 0;\r\n post();\r\n break;\r\n }\r\n\r\n case \"START\": {\r\n if (!state || interval !== null) return;\r\n interval = setInterval(runTick, TICK_MS);\r\n break;\r\n }\r\n\r\n case \"PAUSE\": {\r\n if (interval !== null) {\r\n clearInterval(interval);\r\n interval = null;\r\n }\r\n break;\r\n }\r\n\r\n case \"STEP\": {\r\n runTick();\r\n break;\r\n }\r\n case \"SET_CONFIG\": {\r\n if (!state) return;\r\n\r\n state.config = {\r\n ...state.config,\r\n ...msg.payload,\r\n };\r\n\r\n post();\r\n break;\r\n }\r\n case \"ADD_TASK\": {\r\n if (!state) return;\r\n\r\n state.tasks.push({\r\n ...msg.payload,\r\n createdAt: state.time,\r\n });\r\n\r\n break;\r\n }\r\n\r\n case \"SET_POLICY\": {\r\n if (!state) return;\r\n state.policy = msg.payload as PolicyName;\r\n break;\r\n }\r\n\r\n case \"SET_RESOURCES\": {\r\n if (!state) return;\r\n state.resources = {\r\n ...state.resources,\r\n ...(msg.payload as Partial<SystemResources>),\r\n };\r\n for (const w of state.workers) {\r\n w.maxCPU = state.resources.totalCPU;\r\n w.maxRAM = state.resources.totalRAM;\r\n }\r\n post();\r\n break;\r\n }\r\n case \"EXPORT_REPLAY\": {\r\n postMessage({\r\n type: \"REPLAY_DATA\",\r\n payload: {\r\n seed: currentSeed,\r\n events: eventLog,\r\n },\r\n });\r\n break;\r\n }\r\n\r\n case \"REPLAY\": {\r\n if (!initialSnapshot) return;\r\n\r\n // Reset system\r\n state = structuredClone(initialSnapshot);\r\n rng = createRNG(msg.payload.seed);\r\n sustainedPressureTicks = 0;\r\n\r\n // Re-apply events deterministically\r\n for (const e of msg.payload.events) {\r\n applyEvent(e.message);\r\n }\r\n\r\n post();\r\n break;\r\n }\r\n }\r\n};\r\n\r\nfunction runTick() {\r\n if (!state) return;\r\n\r\n state = tick(state, TICK_MS / 1000, rng);\r\n\r\n if (state.metrics.pressure > COLLAPSE_PRESSURE) {\r\n sustainedPressureTicks++;\r\n } else {\r\n sustainedPressureTicks = 0;\r\n }\r\n\r\n if (\r\n state.metrics.stabilityIndex <= 15 ||\r\n sustainedPressureTicks >= COLLAPSE_TICKS\r\n ) {\r\n postMessage({\r\n type: \"COLLAPSE\",\r\n payload: {\r\n time: state.time,\r\n stabilityIndex: state.metrics.stabilityIndex,\r\n pressure: state.metrics.pressure,\r\n reason:\r\n sustainedPressureTicks >= COLLAPSE_TICKS\r\n ? \"Sustained system pressure\"\r\n : \"System stability degraded beyond recovery\",\r\n },\r\n });\r\n\r\n clearInterval(interval!);\r\n interval = null;\r\n return;\r\n }\r\n\r\n post();\r\n}\r\n\r\nfunction post() {\r\n postMessage({\r\n type: \"STATE\",\r\n payload: state,\r\n });\r\n}\r\n\r\nlet initialSnapshot: SystemState | null = null;\r\n\r\nfunction reset() {\r\n if (!initialSnapshot) return;\r\n\r\n state = structuredClone(initialSnapshot);\r\n rng = createRNG(currentSeed);\r\n}\r\n\r\nfunction applyEvent(msg: any) {\r\n switch (msg.type) {\r\n case \"ADD_TASK\":\r\n state?.tasks.push({\r\n ...msg.payload,\r\n createdAt: state.time,\r\n });\r\n break;\r\n\r\n case \"SET_POLICY\":\r\n if (state) state.policy = msg.payload;\r\n break;\r\n\r\n case \"SET_RESOURCES\":\r\n if (state) {\r\n state.resources = {\r\n ...state.resources,\r\n ...msg.payload,\r\n };\r\n }\r\n break;\r\n\r\n case \"START\":\r\n if (!interval) {\r\n interval = setInterval(runTick, TICK_MS);\r\n }\r\n break;\r\n\r\n case \"PAUSE\":\r\n if (interval) {\r\n clearInterval(interval);\r\n interval = null;\r\n }\r\n break;\r\n }\r\n}\r\n"],"mappings":"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","names":["state","state","rng","state","rng","state","rng"]}
1
+ {"version":3,"sources":["../src/engine/policy.ts","../src/engine/random.ts","../src/engine/metrics.ts","../src/engine/cost.ts","../src/engine/execution.ts","../src/engine/scheduler.ts","../src/engine/tick.ts","../src/worker/simulator.worker.ts"],"sourcesContent":["export type PolicyName = \"FAIRNESS\" | \"BALANCED\" | \"THROUGHPUT\";\r\n\r\nexport type Policy = {\r\n starvationWeight: number;\r\n latenessWeight: number;\r\n failureWeight: number;\r\n instabilityWeight: number;\r\n};\r\n\r\nexport const POLICIES: Record<PolicyName, Policy> = {\r\n FAIRNESS: {\r\n starvationWeight: 2,\r\n latenessWeight: 0.8,\r\n failureWeight: 1,\r\n instabilityWeight: 0.5,\r\n },\r\n BALANCED: {\r\n starvationWeight: 0.5,\r\n latenessWeight: 1,\r\n failureWeight: 2,\r\n instabilityWeight: 1,\r\n },\r\n THROUGHPUT: {\r\n starvationWeight: 0.1,\r\n latenessWeight: 1.5,\r\n failureWeight: 3,\r\n instabilityWeight: 2,\r\n },\r\n};\r\n","export type RNG = () => number;\r\n\r\nexport function createRNG(seed: number): RNG {\r\n let t = seed >>> 0;\r\n\r\n return function () {\r\n t += 0x6d2b79f5;\r\n let r = Math.imul(t ^ (t >>> 15), 1 | t);\r\n r ^= r + Math.imul(r ^ (r >>> 7), 61 | r);\r\n return ((r ^ (r >>> 14)) >>> 0) / 4294967296;\r\n };\r\n}\r\n","import { SystemState } from \"../core/state\";\r\n\r\nexport function computeMetrics(state: SystemState): SystemState {\r\n let usedCPU = 0;\r\n let usedRAM = 0;\r\n\r\n for (const task of state.tasks) {\r\n if (task.status === \"running\") {\r\n usedCPU += task.execution.cpuCurve.base;\r\n usedRAM += task.execution.ramCurve.base;\r\n }\r\n }\r\n\r\n const cpuPressure = usedCPU / state.resources.totalCPU;\r\n const ramPressure = usedRAM / state.resources.totalRAM;\r\n const pressure = Math.max(cpuPressure, ramPressure);\r\n\r\n const queueLength = state.tasks.filter((t) => t.status === \"queued\").length;\r\n\r\n const failed = state.tasks.filter((t) => t.status === \"failed\").length;\r\n\r\n // 🔥 System Stability Index (0–100)\r\n const pressurePenalty = Math.min(pressure * 50, 60);\r\n const queuePenalty = Math.min(queueLength * 3, 25);\r\n const failurePenalty = Math.min(failed * 5, 40);\r\n\r\n const stabilityIndex = Math.max(\r\n 0,\r\n Math.round(100 - pressurePenalty - queuePenalty - failurePenalty)\r\n );\r\n\r\n state.metrics = {\r\n ...state.metrics,\r\n cpuPressure,\r\n ramPressure,\r\n pressure,\r\n queueLength,\r\n completed: state.tasks.filter((t) => t.status === \"completed\").length,\r\n failed,\r\n stabilityIndex,\r\n };\r\n\r\n return state;\r\n}\r\n","import { Task } from \"../core/task\";\r\nimport { SystemState } from \"../core/state\";\r\nimport { POLICIES } from \"./policy\";\r\n\r\nexport type CostBreakdown = {\r\n starvation: number;\r\n lateness: number;\r\n failureRisk: number;\r\n instability: number;\r\n total: number;\r\n};\r\n\r\nexport function computeTaskCost(task: Task, state: SystemState): CostBreakdown {\r\n const policy = POLICIES[state.policy];\r\n const now = state.time;\r\n const pressure = state.metrics.pressure;\r\n\r\n // --- Starvation ---\r\n const waitingTime = task.startedAt === undefined ? now - task.createdAt : 0;\r\n\r\n const starvation = waitingTime * policy.starvationWeight;\r\n\r\n // --- Lateness ---\r\n const latenessTime = Math.max(0, now - task.deadline);\r\n\r\n const lateness = latenessTime * policy.latenessWeight;\r\n\r\n // --- Failure Risk (expected loss) ---\r\n const failureRisk = task.failureProbability * pressure * policy.failureWeight;\r\n\r\n // --- System Instability ---\r\n const instability = pressure * pressure * policy.instabilityWeight;\r\n\r\n const total = starvation + lateness + failureRisk + instability;\r\n\r\n return {\r\n starvation,\r\n lateness,\r\n failureRisk,\r\n instability,\r\n total,\r\n };\r\n}\r\n","import { ResourceCurve } from \"../core/task\";\r\nimport { RNG } from \"./random\";\r\n\r\nexport function sampleUsage(curve: ResourceCurve, rng: RNG): number {\r\n const spread = curve.peak - curve.base;\r\n\r\n // centered noise in [-0.5, 0.5]\r\n const noise = (rng() - 0.5) * 2;\r\n\r\n const usage = curve.base + spread * curve.variance * noise;\r\n\r\n return Math.max(0, usage);\r\n}\r\n\r\nexport function slowdownFactor(pressure: number): number {\r\n return 1 + pressure * pressure;\r\n}\r\n","import { SystemState } from \"../core/state\";\r\nimport { computeTaskCost } from \"./cost\";\r\nimport { slowdownFactor } from \"./execution\";\r\nimport { RNG } from \"./random\";\r\nimport { sampleUsage } from \"./execution\";\r\n\r\nconst MAX_PRESSURE = 1.2;\r\n\r\nfunction phaseFailureMultiplier(phase: \"cpu\" | \"io\") {\r\n return phase === \"io\" ? 1.6 : 1.0;\r\n}\r\n\r\nexport function schedule(\r\n state: SystemState,\r\n dt: number,\r\n rng: RNG\r\n): SystemState {\r\n const now = state.time;\r\n\r\n /* =========================================================\r\n 1. STARVATION FAILURE (queued too long, under pressure)\r\n ========================================================= */\r\n\r\n for (const t of state.tasks) {\r\n if (\r\n t.status === \"queued\" &&\r\n t.maxQueueTime !== undefined &&\r\n now - t.createdAt > t.maxQueueTime &&\r\n state.metrics.pressure > 1\r\n ) {\r\n t.status = \"failed\";\r\n t.failureType = \"starvation\";\r\n t.failureReason =\r\n \"Starvation: task waited too long in queue under pressure\";\r\n t.finishedAt = now;\r\n }\r\n }\r\n\r\n const queued = state.tasks.filter((t) => t.status === \"queued\");\r\n\r\n /* =========================================================\r\n 2. LOAD SHEDDING (system protection)\r\n ========================================================= */\r\n\r\n if (state.metrics.pressure > MAX_PRESSURE && queued.length > 0) {\r\n const worst = queued\r\n .map((t) => ({ t, cost: computeTaskCost(t, state).total }))\r\n .sort((a, b) => b.cost - a.cost)[0].t;\r\n\r\n worst.status = \"failed\";\r\n worst.failureType = \"load_shed\";\r\n worst.failureReason = \"Load shed: system pressure exceeded safe threshold\";\r\n worst.finishedAt = now;\r\n }\r\n\r\n /* =========================================================\r\n 3. ADMISSION CONTROL (concurrency-limited)\r\n ========================================================= */\r\n\r\n const queuedWithCost = state.tasks\r\n .filter((t) => t.status === \"queued\")\r\n .map((t) => ({ t, cost: computeTaskCost(t, state).total }));\r\n\r\n let sortedQueued;\r\n\r\n switch (state.policy) {\r\n case \"THROUGHPUT\":\r\n // favor cheap tasks → maximize completions\r\n sortedQueued = queuedWithCost.sort((a, b) => a.cost - b.cost);\r\n break;\r\n\r\n case \"FAIRNESS\":\r\n // favor oldest tasks\r\n sortedQueued = queuedWithCost.sort(\r\n (a, b) => a.t.createdAt - b.t.createdAt\r\n );\r\n break;\r\n\r\n case \"BALANCED\":\r\n default:\r\n // mix age + cost\r\n sortedQueued = queuedWithCost.sort(\r\n (a, b) =>\r\n 0.5 * (a.cost - b.cost) + 0.5 * (a.t.createdAt - b.t.createdAt)\r\n );\r\n }\r\n\r\n let runningCount = state.tasks.filter((t) => t.status === \"running\").length;\r\n\r\n for (const { t } of sortedQueued) {\r\n if (runningCount >= state.config.maxConcurrentTasks) break;\r\n\r\n t.status = \"running\";\r\n t.startedAt = now;\r\n t.expectedEndAt = now + t.execution.meanDuration;\r\n\r\n t.currentRAM = sampleUsage(t.execution.ramCurve, rng);\r\n\r\n runningCount++;\r\n }\r\n\r\n /* =========================================================\r\n 4. EXECUTE RUNNING TASKS\r\n ========================================================= */\r\n\r\n const running = state.tasks.filter((t) => t.status === \"running\");\r\n\r\n /* ---------- CPU SHARING ---------- */\r\n const cpuTasks = running.filter((t) => t.phase === \"cpu\");\r\n const cpuPerTask =\r\n cpuTasks.length > 0 ? state.resources.totalCPU / cpuTasks.length : 0;\r\n\r\n /* ---------- RAM ACCUMULATION ---------- */\r\n let totalUsedRAM = 0;\r\n for (const t of running) {\r\n if (t.currentRAM !== undefined) {\r\n totalUsedRAM += t.currentRAM;\r\n }\r\n }\r\n\r\n state.metrics.ramPressure = totalUsedRAM / state.resources.totalRAM;\r\n\r\n /* ---------- EXECUTION LOOP ---------- */\r\n for (const t of running) {\r\n const cpuSlow = slowdownFactor(state.metrics.cpuPressure);\r\n\r\n if (t.phase === \"cpu\") {\r\n t.progress +=\r\n ((cpuPerTask / state.resources.totalCPU) *\r\n (dt / t.execution.meanDuration)) /\r\n cpuSlow;\r\n } else {\r\n const ramSlow = 1 + Math.max(0, state.metrics.ramPressure - 1);\r\n\r\n t.progress += (0.3 * dt) / t.execution.meanDuration / ramSlow;\r\n }\r\n\r\n /* ---------- TIMEOUT FAILURE ---------- */\r\n if (t.deadline !== undefined && t.startedAt !== undefined) {\r\n const effectiveDeadline =\r\n t.deadline * Math.max(1, state.metrics.pressure);\r\n\r\n if (now - t.startedAt > effectiveDeadline && state.metrics.pressure > 1) {\r\n t.status = \"failed\";\r\n t.failureType = \"timeout\";\r\n t.failureReason = \"Deadline exceeded under sustained pressure\";\r\n t.finishedAt = now;\r\n continue;\r\n }\r\n }\r\n\r\n /* ---------- PRESSURE-CORRELATED FAILURE ---------- */\r\n const runTime = t.startedAt !== undefined ? now - t.startedAt : 0;\r\n\r\n const fatigueMultiplier = 1 + Math.min(runTime / 10, 1);\r\n\r\n const lambda =\r\n t.failureProbability *\r\n phaseFailureMultiplier(t.phase) *\r\n fatigueMultiplier *\r\n state.metrics.pressure;\r\n\r\n const perTickRisk = 1 - Math.exp(-lambda * dt);\r\n\r\n if (rng() < perTickRisk) {\r\n t.status = \"failed\";\r\n t.failureType = \"pressure\";\r\n t.failureReason = `Execution failure (λ=${lambda.toFixed(3)})`;\r\n t.finishedAt = now;\r\n continue;\r\n }\r\n\r\n /* ---------- COMPLETION ---------- */\r\n if (t.progress >= 1) {\r\n t.status = \"completed\";\r\n t.finishedAt = now;\r\n }\r\n\r\n /* ---------- ASYNC ILLUSION ---------- */\r\n if (rng() < 0.15) {\r\n t.phase = t.phase === \"cpu\" ? \"io\" : \"cpu\";\r\n }\r\n }\r\n\r\n return state;\r\n}\r\n","import { SystemState } from \"../core/state\";\r\nimport { computeMetrics } from \"./metrics\";\r\nimport { schedule } from \"./scheduler\";\r\nimport { RNG } from \"./random\";\r\n\r\nexport function tick(state: SystemState, dt: number, rng: RNG): SystemState {\r\n let next = { ...state, time: state.time + dt };\r\n\r\n next = computeMetrics(next);\r\n next = schedule(next, dt, rng);\r\n next = computeMetrics(next);\r\n\r\n return next;\r\n}\r\n","/// <reference lib=\"webworker\" />\r\nconsole.log(\"🔥 WORKER FILE EXECUTED\");\r\nimport { tick } from \"../engine/tick\";\r\nimport { SystemState } from \"../core/state\";\r\nimport { Task } from \"../core/task\";\r\nimport { PolicyName } from \"../engine/policy\";\r\nimport { SystemResources } from \"../core/resources\";\r\nimport { createRNG } from \"../engine/random\";\r\nlet currentSeed: number = 1;\r\nlet rng = createRNG(currentSeed);\r\n\r\nlet state: SystemState | null = null;\r\nlet interval: ReturnType<typeof setInterval> | null = null;\r\n\r\nconst TICK_MS = 100;\r\nlet sustainedPressureTicks = 0;\r\nconst COLLAPSE_PRESSURE = 1.5;\r\nconst COLLAPSE_TICKS = 10;\r\n\r\nlet eventLog: Array<{\r\n time: number;\r\n message: any;\r\n}> = [];\r\n\r\nself.onmessage = (event: MessageEvent) => {\r\n const msg = event.data;\r\n // Log user actions (but NOT INIT or STATE)\r\n if (state && ![\"STATE\", \"INIT\"].includes(msg.type)) {\r\n eventLog.push({\r\n time: state.time,\r\n message: msg,\r\n });\r\n }\r\n switch (msg.type) {\r\n case \"INIT\": {\r\n state = structuredClone(msg.payload.state);\r\n initialSnapshot = structuredClone(msg.payload.state);\r\n currentSeed = msg.payload.seed ?? 1;\r\n rng = createRNG(currentSeed);\r\n eventLog = [];\r\n sustainedPressureTicks = 0;\r\n post();\r\n break;\r\n }\r\n\r\n case \"START\": {\r\n if (!state || interval !== null) return;\r\n interval = setInterval(runTick, TICK_MS);\r\n break;\r\n }\r\n\r\n case \"PAUSE\": {\r\n if (interval !== null) {\r\n clearInterval(interval);\r\n interval = null;\r\n }\r\n break;\r\n }\r\n\r\n case \"STEP\": {\r\n runTick();\r\n break;\r\n }\r\n case \"SET_CONFIG\": {\r\n if (!state) return;\r\n\r\n state.config = {\r\n ...state.config,\r\n ...msg.payload,\r\n };\r\n\r\n post();\r\n break;\r\n }\r\n case \"ADD_TASK\": {\r\n if (!state) return;\r\n\r\n state.tasks.push({\r\n ...msg.payload,\r\n createdAt: state.time,\r\n });\r\n\r\n break;\r\n }\r\n\r\n case \"SET_POLICY\": {\r\n if (!state) return;\r\n state.policy = msg.payload as PolicyName;\r\n break;\r\n }\r\n\r\n case \"SET_RESOURCES\": {\r\n if (!state) return;\r\n state.resources = {\r\n ...state.resources,\r\n ...(msg.payload as Partial<SystemResources>),\r\n };\r\n for (const w of state.workers) {\r\n w.maxCPU = state.resources.totalCPU;\r\n w.maxRAM = state.resources.totalRAM;\r\n }\r\n post();\r\n break;\r\n }\r\n case \"EXPORT_REPLAY\": {\r\n postMessage({\r\n type: \"REPLAY_DATA\",\r\n payload: {\r\n seed: currentSeed,\r\n events: eventLog,\r\n },\r\n });\r\n break;\r\n }\r\n\r\n case \"REPLAY\": {\r\n if (!initialSnapshot) return;\r\n\r\n // Reset system\r\n state = structuredClone(initialSnapshot);\r\n rng = createRNG(msg.payload.seed);\r\n sustainedPressureTicks = 0;\r\n\r\n // Re-apply events deterministically\r\n for (const e of msg.payload.events) {\r\n applyEvent(e.message);\r\n }\r\n\r\n post();\r\n break;\r\n }\r\n }\r\n};\r\n\r\nfunction runTick() {\r\n if (!state) return;\r\n\r\n state = tick(state, TICK_MS / 1000, rng);\r\n\r\n if (state.metrics.pressure > COLLAPSE_PRESSURE) {\r\n sustainedPressureTicks++;\r\n } else {\r\n sustainedPressureTicks = 0;\r\n }\r\n\r\n if (\r\n state.metrics.stabilityIndex <= 15 ||\r\n sustainedPressureTicks >= COLLAPSE_TICKS\r\n ) {\r\n postMessage({\r\n type: \"COLLAPSE\",\r\n payload: {\r\n time: state.time,\r\n stabilityIndex: state.metrics.stabilityIndex,\r\n pressure: state.metrics.pressure,\r\n reason:\r\n sustainedPressureTicks >= COLLAPSE_TICKS\r\n ? \"Sustained system pressure\"\r\n : \"System stability degraded beyond recovery\",\r\n },\r\n });\r\n\r\n clearInterval(interval!);\r\n interval = null;\r\n return;\r\n }\r\n\r\n post();\r\n}\r\n\r\nfunction post() {\r\n postMessage({\r\n type: \"STATE\",\r\n payload: state,\r\n });\r\n}\r\n\r\nlet initialSnapshot: SystemState | null = null;\r\n\r\nfunction reset() {\r\n if (!initialSnapshot) return;\r\n\r\n state = structuredClone(initialSnapshot);\r\n rng = createRNG(currentSeed);\r\n}\r\n\r\nfunction applyEvent(msg: any) {\r\n switch (msg.type) {\r\n case \"ADD_TASK\":\r\n state?.tasks.push({\r\n ...msg.payload,\r\n createdAt: state.time,\r\n });\r\n break;\r\n\r\n case \"SET_POLICY\":\r\n if (state) state.policy = msg.payload;\r\n break;\r\n\r\n case \"SET_RESOURCES\":\r\n if (state) {\r\n state.resources = {\r\n ...state.resources,\r\n ...msg.payload,\r\n };\r\n }\r\n break;\r\n\r\n case \"START\":\r\n if (!interval) {\r\n interval = setInterval(runTick, TICK_MS);\r\n }\r\n break;\r\n\r\n case \"PAUSE\":\r\n if (interval) {\r\n clearInterval(interval);\r\n interval = null;\r\n }\r\n break;\r\n }\r\n}\r\n"],"mappings":"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","names":["state","state","rng","state","rng","state","rng"]}
package/dist/worker.js CHANGED
@@ -99,6 +99,7 @@ function schedule(state2, dt, rng2) {
99
99
  t.status = "failed";
100
100
  t.failureType = "starvation";
101
101
  t.failureReason = "Starvation: task waited too long in queue under pressure";
102
+ t.finishedAt = now;
102
103
  }
103
104
  }
104
105
  const queued = state2.tasks.filter((t) => t.status === "queued");
@@ -107,6 +108,7 @@ function schedule(state2, dt, rng2) {
107
108
  worst.status = "failed";
108
109
  worst.failureType = "load_shed";
109
110
  worst.failureReason = "Load shed: system pressure exceeded safe threshold";
111
+ worst.finishedAt = now;
110
112
  }
111
113
  const queuedWithCost = state2.tasks.filter((t) => t.status === "queued").map((t) => ({ t, cost: computeTaskCost(t, state2).total }));
112
114
  let sortedQueued;
@@ -158,6 +160,7 @@ function schedule(state2, dt, rng2) {
158
160
  t.status = "failed";
159
161
  t.failureType = "timeout";
160
162
  t.failureReason = "Deadline exceeded under sustained pressure";
163
+ t.finishedAt = now;
161
164
  continue;
162
165
  }
163
166
  }
@@ -169,10 +172,12 @@ function schedule(state2, dt, rng2) {
169
172
  t.status = "failed";
170
173
  t.failureType = "pressure";
171
174
  t.failureReason = `Execution failure (\u03BB=${lambda.toFixed(3)})`;
175
+ t.finishedAt = now;
172
176
  continue;
173
177
  }
174
178
  if (t.progress >= 1) {
175
179
  t.status = "completed";
180
+ t.finishedAt = now;
176
181
  }
177
182
  if (rng2() < 0.15) {
178
183
  t.phase = t.phase === "cpu" ? "io" : "cpu";
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/engine/metrics.ts","../src/engine/policy.ts","../src/engine/cost.ts","../src/engine/execution.ts","../src/engine/scheduler.ts","../src/engine/tick.ts","../src/engine/random.ts","../src/worker/simulator.worker.ts"],"sourcesContent":["import { SystemState } from \"../core/state\";\r\n\r\nexport function computeMetrics(state: SystemState): SystemState {\r\n let usedCPU = 0;\r\n let usedRAM = 0;\r\n\r\n for (const task of state.tasks) {\r\n if (task.status === \"running\") {\r\n usedCPU += task.execution.cpuCurve.base;\r\n usedRAM += task.execution.ramCurve.base;\r\n }\r\n }\r\n\r\n const cpuPressure = usedCPU / state.resources.totalCPU;\r\n const ramPressure = usedRAM / state.resources.totalRAM;\r\n const pressure = Math.max(cpuPressure, ramPressure);\r\n\r\n const queueLength = state.tasks.filter((t) => t.status === \"queued\").length;\r\n\r\n const failed = state.tasks.filter((t) => t.status === \"failed\").length;\r\n\r\n // 🔥 System Stability Index (0–100)\r\n const pressurePenalty = Math.min(pressure * 50, 60);\r\n const queuePenalty = Math.min(queueLength * 3, 25);\r\n const failurePenalty = Math.min(failed * 5, 40);\r\n\r\n const stabilityIndex = Math.max(\r\n 0,\r\n Math.round(100 - pressurePenalty - queuePenalty - failurePenalty)\r\n );\r\n\r\n state.metrics = {\r\n ...state.metrics,\r\n cpuPressure,\r\n ramPressure,\r\n pressure,\r\n queueLength,\r\n completed: state.tasks.filter((t) => t.status === \"completed\").length,\r\n failed,\r\n stabilityIndex,\r\n };\r\n\r\n return state;\r\n}\r\n","export type PolicyName = \"FAIRNESS\" | \"BALANCED\" | \"THROUGHPUT\";\r\n\r\nexport type Policy = {\r\n starvationWeight: number;\r\n latenessWeight: number;\r\n failureWeight: number;\r\n instabilityWeight: number;\r\n};\r\n\r\nexport const POLICIES: Record<PolicyName, Policy> = {\r\n FAIRNESS: {\r\n starvationWeight: 2,\r\n latenessWeight: 0.8,\r\n failureWeight: 1,\r\n instabilityWeight: 0.5,\r\n },\r\n BALANCED: {\r\n starvationWeight: 0.5,\r\n latenessWeight: 1,\r\n failureWeight: 2,\r\n instabilityWeight: 1,\r\n },\r\n THROUGHPUT: {\r\n starvationWeight: 0.1,\r\n latenessWeight: 1.5,\r\n failureWeight: 3,\r\n instabilityWeight: 2,\r\n },\r\n};\r\n","import { Task } from \"../core/task\";\r\nimport { SystemState } from \"../core/state\";\r\nimport { POLICIES } from \"./policy\";\r\n\r\nexport type CostBreakdown = {\r\n starvation: number;\r\n lateness: number;\r\n failureRisk: number;\r\n instability: number;\r\n total: number;\r\n};\r\n\r\nexport function computeTaskCost(task: Task, state: SystemState): CostBreakdown {\r\n const policy = POLICIES[state.policy];\r\n const now = state.time;\r\n const pressure = state.metrics.pressure;\r\n\r\n // --- Starvation ---\r\n const waitingTime = task.startedAt === undefined ? now - task.createdAt : 0;\r\n\r\n const starvation = waitingTime * policy.starvationWeight;\r\n\r\n // --- Lateness ---\r\n const latenessTime = Math.max(0, now - task.deadline);\r\n\r\n const lateness = latenessTime * policy.latenessWeight;\r\n\r\n // --- Failure Risk (expected loss) ---\r\n const failureRisk = task.failureProbability * pressure * policy.failureWeight;\r\n\r\n // --- System Instability ---\r\n const instability = pressure * pressure * policy.instabilityWeight;\r\n\r\n const total = starvation + lateness + failureRisk + instability;\r\n\r\n return {\r\n starvation,\r\n lateness,\r\n failureRisk,\r\n instability,\r\n total,\r\n };\r\n}\r\n","import { ResourceCurve } from \"../core/task\";\r\nimport { RNG } from \"./random\";\r\n\r\nexport function sampleUsage(curve: ResourceCurve, rng: RNG): number {\r\n const spread = curve.peak - curve.base;\r\n\r\n // centered noise in [-0.5, 0.5]\r\n const noise = (rng() - 0.5) * 2;\r\n\r\n const usage = curve.base + spread * curve.variance * noise;\r\n\r\n return Math.max(0, usage);\r\n}\r\n\r\nexport function slowdownFactor(pressure: number): number {\r\n return 1 + pressure * pressure;\r\n}\r\n","import { SystemState } from \"../core/state\";\r\nimport { computeTaskCost } from \"./cost\";\r\nimport { slowdownFactor } from \"./execution\";\r\nimport { RNG } from \"./random\";\r\nimport { sampleUsage } from \"./execution\";\r\n\r\nconst MAX_PRESSURE = 1.2;\r\n\r\nfunction phaseFailureMultiplier(phase: \"cpu\" | \"io\") {\r\n return phase === \"io\" ? 1.6 : 1.0;\r\n}\r\n\r\nexport function schedule(\r\n state: SystemState,\r\n dt: number,\r\n rng: RNG\r\n): SystemState {\r\n const now = state.time;\r\n\r\n /* =========================================================\r\n 1. STARVATION FAILURE (queued too long, under pressure)\r\n ========================================================= */\r\n\r\n for (const t of state.tasks) {\r\n if (\r\n t.status === \"queued\" &&\r\n t.maxQueueTime !== undefined &&\r\n now - t.createdAt > t.maxQueueTime &&\r\n state.metrics.pressure > 1\r\n ) {\r\n t.status = \"failed\";\r\n t.failureType = \"starvation\";\r\n t.failureReason =\r\n \"Starvation: task waited too long in queue under pressure\";\r\n }\r\n }\r\n\r\n const queued = state.tasks.filter((t) => t.status === \"queued\");\r\n\r\n /* =========================================================\r\n 2. LOAD SHEDDING (system protection)\r\n ========================================================= */\r\n\r\n if (state.metrics.pressure > MAX_PRESSURE && queued.length > 0) {\r\n const worst = queued\r\n .map((t) => ({ t, cost: computeTaskCost(t, state).total }))\r\n .sort((a, b) => b.cost - a.cost)[0].t;\r\n\r\n worst.status = \"failed\";\r\n worst.failureType = \"load_shed\";\r\n worst.failureReason = \"Load shed: system pressure exceeded safe threshold\";\r\n }\r\n\r\n /* =========================================================\r\n 3. ADMISSION CONTROL (concurrency-limited)\r\n ========================================================= */\r\n\r\n const queuedWithCost = state.tasks\r\n .filter((t) => t.status === \"queued\")\r\n .map((t) => ({ t, cost: computeTaskCost(t, state).total }));\r\n\r\n let sortedQueued;\r\n\r\n switch (state.policy) {\r\n case \"THROUGHPUT\":\r\n // favor cheap tasks → maximize completions\r\n sortedQueued = queuedWithCost.sort((a, b) => a.cost - b.cost);\r\n break;\r\n\r\n case \"FAIRNESS\":\r\n // favor oldest tasks\r\n sortedQueued = queuedWithCost.sort(\r\n (a, b) => a.t.createdAt - b.t.createdAt\r\n );\r\n break;\r\n\r\n case \"BALANCED\":\r\n default:\r\n // mix age + cost\r\n sortedQueued = queuedWithCost.sort(\r\n (a, b) =>\r\n 0.5 * (a.cost - b.cost) + 0.5 * (a.t.createdAt - b.t.createdAt)\r\n );\r\n }\r\n\r\n let runningCount = state.tasks.filter((t) => t.status === \"running\").length;\r\n\r\n for (const { t } of sortedQueued) {\r\n if (runningCount >= state.config.maxConcurrentTasks) break;\r\n\r\n t.status = \"running\";\r\n t.startedAt = now;\r\n t.expectedEndAt = now + t.execution.meanDuration;\r\n\r\n t.currentRAM = sampleUsage(t.execution.ramCurve, rng);\r\n\r\n runningCount++;\r\n }\r\n\r\n /* =========================================================\r\n 4. EXECUTE RUNNING TASKS\r\n ========================================================= */\r\n\r\n const running = state.tasks.filter((t) => t.status === \"running\");\r\n\r\n /* ---------- CPU SHARING ---------- */\r\n const cpuTasks = running.filter((t) => t.phase === \"cpu\");\r\n const cpuPerTask =\r\n cpuTasks.length > 0 ? state.resources.totalCPU / cpuTasks.length : 0;\r\n\r\n /* ---------- RAM ACCUMULATION ---------- */\r\n let totalUsedRAM = 0;\r\n for (const t of running) {\r\n if (t.currentRAM !== undefined) {\r\n totalUsedRAM += t.currentRAM;\r\n }\r\n }\r\n\r\n state.metrics.ramPressure = totalUsedRAM / state.resources.totalRAM;\r\n\r\n /* ---------- EXECUTION LOOP ---------- */\r\n for (const t of running) {\r\n const cpuSlow = slowdownFactor(state.metrics.cpuPressure);\r\n\r\n if (t.phase === \"cpu\") {\r\n t.progress +=\r\n ((cpuPerTask / state.resources.totalCPU) *\r\n (dt / t.execution.meanDuration)) /\r\n cpuSlow;\r\n } else {\r\n const ramSlow = 1 + Math.max(0, state.metrics.ramPressure - 1);\r\n\r\n t.progress += (0.3 * dt) / t.execution.meanDuration / ramSlow;\r\n }\r\n\r\n /* ---------- TIMEOUT FAILURE ---------- */\r\n if (t.deadline !== undefined && t.startedAt !== undefined) {\r\n const effectiveDeadline =\r\n t.deadline * Math.max(1, state.metrics.pressure);\r\n\r\n if (now - t.startedAt > effectiveDeadline && state.metrics.pressure > 1) {\r\n t.status = \"failed\";\r\n t.failureType = \"timeout\";\r\n t.failureReason = \"Deadline exceeded under sustained pressure\";\r\n continue;\r\n }\r\n }\r\n\r\n /* ---------- PRESSURE-CORRELATED FAILURE ---------- */\r\n const runTime = t.startedAt !== undefined ? now - t.startedAt : 0;\r\n\r\n const fatigueMultiplier = 1 + Math.min(runTime / 10, 1);\r\n\r\n const lambda =\r\n t.failureProbability *\r\n phaseFailureMultiplier(t.phase) *\r\n fatigueMultiplier *\r\n state.metrics.pressure;\r\n\r\n const perTickRisk = 1 - Math.exp(-lambda * dt);\r\n\r\n if (rng() < perTickRisk) {\r\n t.status = \"failed\";\r\n t.failureType = \"pressure\";\r\n t.failureReason = `Execution failure (λ=${lambda.toFixed(3)})`;\r\n continue;\r\n }\r\n\r\n /* ---------- COMPLETION ---------- */\r\n if (t.progress >= 1) {\r\n t.status = \"completed\";\r\n }\r\n\r\n /* ---------- ASYNC ILLUSION ---------- */\r\n if (rng() < 0.15) {\r\n t.phase = t.phase === \"cpu\" ? \"io\" : \"cpu\";\r\n }\r\n }\r\n\r\n return state;\r\n}\r\n","import { SystemState } from \"../core/state\";\r\nimport { computeMetrics } from \"./metrics\";\r\nimport { schedule } from \"./scheduler\";\r\nimport { RNG } from \"./random\";\r\n\r\nexport function tick(state: SystemState, dt: number, rng: RNG): SystemState {\r\n let next = { ...state, time: state.time + dt };\r\n\r\n next = computeMetrics(next);\r\n next = schedule(next, dt, rng);\r\n next = computeMetrics(next);\r\n\r\n return next;\r\n}\r\n","export type RNG = () => number;\r\n\r\nexport function createRNG(seed: number): RNG {\r\n let t = seed >>> 0;\r\n\r\n return function () {\r\n t += 0x6d2b79f5;\r\n let r = Math.imul(t ^ (t >>> 15), 1 | t);\r\n r ^= r + Math.imul(r ^ (r >>> 7), 61 | r);\r\n return ((r ^ (r >>> 14)) >>> 0) / 4294967296;\r\n };\r\n}\r\n","/// <reference lib=\"webworker\" />\r\nconsole.log(\"🔥 WORKER FILE EXECUTED\");\r\nimport { tick } from \"../engine/tick\";\r\nimport { SystemState } from \"../core/state\";\r\nimport { Task } from \"../core/task\";\r\nimport { PolicyName } from \"../engine/policy\";\r\nimport { SystemResources } from \"../core/resources\";\r\nimport { createRNG } from \"../engine/random\";\r\nlet currentSeed: number = 1;\r\nlet rng = createRNG(currentSeed);\r\n\r\nlet state: SystemState | null = null;\r\nlet interval: ReturnType<typeof setInterval> | null = null;\r\n\r\nconst TICK_MS = 100;\r\nlet sustainedPressureTicks = 0;\r\nconst COLLAPSE_PRESSURE = 1.5;\r\nconst COLLAPSE_TICKS = 10;\r\n\r\nlet eventLog: Array<{\r\n time: number;\r\n message: any;\r\n}> = [];\r\n\r\nself.onmessage = (event: MessageEvent) => {\r\n const msg = event.data;\r\n // Log user actions (but NOT INIT or STATE)\r\n if (state && ![\"STATE\", \"INIT\"].includes(msg.type)) {\r\n eventLog.push({\r\n time: state.time,\r\n message: msg,\r\n });\r\n }\r\n switch (msg.type) {\r\n case \"INIT\": {\r\n state = structuredClone(msg.payload.state);\r\n initialSnapshot = structuredClone(msg.payload.state);\r\n currentSeed = msg.payload.seed ?? 1;\r\n rng = createRNG(currentSeed);\r\n eventLog = [];\r\n sustainedPressureTicks = 0;\r\n post();\r\n break;\r\n }\r\n\r\n case \"START\": {\r\n if (!state || interval !== null) return;\r\n interval = setInterval(runTick, TICK_MS);\r\n break;\r\n }\r\n\r\n case \"PAUSE\": {\r\n if (interval !== null) {\r\n clearInterval(interval);\r\n interval = null;\r\n }\r\n break;\r\n }\r\n\r\n case \"STEP\": {\r\n runTick();\r\n break;\r\n }\r\n case \"SET_CONFIG\": {\r\n if (!state) return;\r\n\r\n state.config = {\r\n ...state.config,\r\n ...msg.payload,\r\n };\r\n\r\n post();\r\n break;\r\n }\r\n case \"ADD_TASK\": {\r\n if (!state) return;\r\n\r\n state.tasks.push({\r\n ...msg.payload,\r\n createdAt: state.time,\r\n });\r\n\r\n break;\r\n }\r\n\r\n case \"SET_POLICY\": {\r\n if (!state) return;\r\n state.policy = msg.payload as PolicyName;\r\n break;\r\n }\r\n\r\n case \"SET_RESOURCES\": {\r\n if (!state) return;\r\n state.resources = {\r\n ...state.resources,\r\n ...(msg.payload as Partial<SystemResources>),\r\n };\r\n for (const w of state.workers) {\r\n w.maxCPU = state.resources.totalCPU;\r\n w.maxRAM = state.resources.totalRAM;\r\n }\r\n post();\r\n break;\r\n }\r\n case \"EXPORT_REPLAY\": {\r\n postMessage({\r\n type: \"REPLAY_DATA\",\r\n payload: {\r\n seed: currentSeed,\r\n events: eventLog,\r\n },\r\n });\r\n break;\r\n }\r\n\r\n case \"REPLAY\": {\r\n if (!initialSnapshot) return;\r\n\r\n // Reset system\r\n state = structuredClone(initialSnapshot);\r\n rng = createRNG(msg.payload.seed);\r\n sustainedPressureTicks = 0;\r\n\r\n // Re-apply events deterministically\r\n for (const e of msg.payload.events) {\r\n applyEvent(e.message);\r\n }\r\n\r\n post();\r\n break;\r\n }\r\n }\r\n};\r\n\r\nfunction runTick() {\r\n if (!state) return;\r\n\r\n state = tick(state, TICK_MS / 1000, rng);\r\n\r\n if (state.metrics.pressure > COLLAPSE_PRESSURE) {\r\n sustainedPressureTicks++;\r\n } else {\r\n sustainedPressureTicks = 0;\r\n }\r\n\r\n if (\r\n state.metrics.stabilityIndex <= 15 ||\r\n sustainedPressureTicks >= COLLAPSE_TICKS\r\n ) {\r\n postMessage({\r\n type: \"COLLAPSE\",\r\n payload: {\r\n time: state.time,\r\n stabilityIndex: state.metrics.stabilityIndex,\r\n pressure: state.metrics.pressure,\r\n reason:\r\n sustainedPressureTicks >= COLLAPSE_TICKS\r\n ? \"Sustained system pressure\"\r\n : \"System stability degraded beyond recovery\",\r\n },\r\n });\r\n\r\n clearInterval(interval!);\r\n interval = null;\r\n return;\r\n }\r\n\r\n post();\r\n}\r\n\r\nfunction post() {\r\n postMessage({\r\n type: \"STATE\",\r\n payload: state,\r\n });\r\n}\r\n\r\nlet initialSnapshot: SystemState | null = null;\r\n\r\nfunction reset() {\r\n if (!initialSnapshot) return;\r\n\r\n state = structuredClone(initialSnapshot);\r\n rng = createRNG(currentSeed);\r\n}\r\n\r\nfunction applyEvent(msg: any) {\r\n switch (msg.type) {\r\n case \"ADD_TASK\":\r\n state?.tasks.push({\r\n ...msg.payload,\r\n createdAt: state.time,\r\n });\r\n break;\r\n\r\n case \"SET_POLICY\":\r\n if (state) state.policy = msg.payload;\r\n break;\r\n\r\n case \"SET_RESOURCES\":\r\n if (state) {\r\n state.resources = {\r\n ...state.resources,\r\n ...msg.payload,\r\n };\r\n }\r\n break;\r\n\r\n case \"START\":\r\n if (!interval) {\r\n interval = setInterval(runTick, TICK_MS);\r\n }\r\n break;\r\n\r\n case \"PAUSE\":\r\n if (interval) {\r\n clearInterval(interval);\r\n interval = null;\r\n }\r\n break;\r\n }\r\n}\r\n"],"mappings":"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","names":["state","state","rng","state","rng","state","rng"]}
1
+ {"version":3,"sources":["../src/engine/metrics.ts","../src/engine/policy.ts","../src/engine/cost.ts","../src/engine/execution.ts","../src/engine/scheduler.ts","../src/engine/tick.ts","../src/engine/random.ts","../src/worker/simulator.worker.ts"],"sourcesContent":["import { SystemState } from \"../core/state\";\r\n\r\nexport function computeMetrics(state: SystemState): SystemState {\r\n let usedCPU = 0;\r\n let usedRAM = 0;\r\n\r\n for (const task of state.tasks) {\r\n if (task.status === \"running\") {\r\n usedCPU += task.execution.cpuCurve.base;\r\n usedRAM += task.execution.ramCurve.base;\r\n }\r\n }\r\n\r\n const cpuPressure = usedCPU / state.resources.totalCPU;\r\n const ramPressure = usedRAM / state.resources.totalRAM;\r\n const pressure = Math.max(cpuPressure, ramPressure);\r\n\r\n const queueLength = state.tasks.filter((t) => t.status === \"queued\").length;\r\n\r\n const failed = state.tasks.filter((t) => t.status === \"failed\").length;\r\n\r\n // 🔥 System Stability Index (0–100)\r\n const pressurePenalty = Math.min(pressure * 50, 60);\r\n const queuePenalty = Math.min(queueLength * 3, 25);\r\n const failurePenalty = Math.min(failed * 5, 40);\r\n\r\n const stabilityIndex = Math.max(\r\n 0,\r\n Math.round(100 - pressurePenalty - queuePenalty - failurePenalty)\r\n );\r\n\r\n state.metrics = {\r\n ...state.metrics,\r\n cpuPressure,\r\n ramPressure,\r\n pressure,\r\n queueLength,\r\n completed: state.tasks.filter((t) => t.status === \"completed\").length,\r\n failed,\r\n stabilityIndex,\r\n };\r\n\r\n return state;\r\n}\r\n","export type PolicyName = \"FAIRNESS\" | \"BALANCED\" | \"THROUGHPUT\";\r\n\r\nexport type Policy = {\r\n starvationWeight: number;\r\n latenessWeight: number;\r\n failureWeight: number;\r\n instabilityWeight: number;\r\n};\r\n\r\nexport const POLICIES: Record<PolicyName, Policy> = {\r\n FAIRNESS: {\r\n starvationWeight: 2,\r\n latenessWeight: 0.8,\r\n failureWeight: 1,\r\n instabilityWeight: 0.5,\r\n },\r\n BALANCED: {\r\n starvationWeight: 0.5,\r\n latenessWeight: 1,\r\n failureWeight: 2,\r\n instabilityWeight: 1,\r\n },\r\n THROUGHPUT: {\r\n starvationWeight: 0.1,\r\n latenessWeight: 1.5,\r\n failureWeight: 3,\r\n instabilityWeight: 2,\r\n },\r\n};\r\n","import { Task } from \"../core/task\";\r\nimport { SystemState } from \"../core/state\";\r\nimport { POLICIES } from \"./policy\";\r\n\r\nexport type CostBreakdown = {\r\n starvation: number;\r\n lateness: number;\r\n failureRisk: number;\r\n instability: number;\r\n total: number;\r\n};\r\n\r\nexport function computeTaskCost(task: Task, state: SystemState): CostBreakdown {\r\n const policy = POLICIES[state.policy];\r\n const now = state.time;\r\n const pressure = state.metrics.pressure;\r\n\r\n // --- Starvation ---\r\n const waitingTime = task.startedAt === undefined ? now - task.createdAt : 0;\r\n\r\n const starvation = waitingTime * policy.starvationWeight;\r\n\r\n // --- Lateness ---\r\n const latenessTime = Math.max(0, now - task.deadline);\r\n\r\n const lateness = latenessTime * policy.latenessWeight;\r\n\r\n // --- Failure Risk (expected loss) ---\r\n const failureRisk = task.failureProbability * pressure * policy.failureWeight;\r\n\r\n // --- System Instability ---\r\n const instability = pressure * pressure * policy.instabilityWeight;\r\n\r\n const total = starvation + lateness + failureRisk + instability;\r\n\r\n return {\r\n starvation,\r\n lateness,\r\n failureRisk,\r\n instability,\r\n total,\r\n };\r\n}\r\n","import { ResourceCurve } from \"../core/task\";\r\nimport { RNG } from \"./random\";\r\n\r\nexport function sampleUsage(curve: ResourceCurve, rng: RNG): number {\r\n const spread = curve.peak - curve.base;\r\n\r\n // centered noise in [-0.5, 0.5]\r\n const noise = (rng() - 0.5) * 2;\r\n\r\n const usage = curve.base + spread * curve.variance * noise;\r\n\r\n return Math.max(0, usage);\r\n}\r\n\r\nexport function slowdownFactor(pressure: number): number {\r\n return 1 + pressure * pressure;\r\n}\r\n","import { SystemState } from \"../core/state\";\r\nimport { computeTaskCost } from \"./cost\";\r\nimport { slowdownFactor } from \"./execution\";\r\nimport { RNG } from \"./random\";\r\nimport { sampleUsage } from \"./execution\";\r\n\r\nconst MAX_PRESSURE = 1.2;\r\n\r\nfunction phaseFailureMultiplier(phase: \"cpu\" | \"io\") {\r\n return phase === \"io\" ? 1.6 : 1.0;\r\n}\r\n\r\nexport function schedule(\r\n state: SystemState,\r\n dt: number,\r\n rng: RNG\r\n): SystemState {\r\n const now = state.time;\r\n\r\n /* =========================================================\r\n 1. STARVATION FAILURE (queued too long, under pressure)\r\n ========================================================= */\r\n\r\n for (const t of state.tasks) {\r\n if (\r\n t.status === \"queued\" &&\r\n t.maxQueueTime !== undefined &&\r\n now - t.createdAt > t.maxQueueTime &&\r\n state.metrics.pressure > 1\r\n ) {\r\n t.status = \"failed\";\r\n t.failureType = \"starvation\";\r\n t.failureReason =\r\n \"Starvation: task waited too long in queue under pressure\";\r\n t.finishedAt = now;\r\n }\r\n }\r\n\r\n const queued = state.tasks.filter((t) => t.status === \"queued\");\r\n\r\n /* =========================================================\r\n 2. LOAD SHEDDING (system protection)\r\n ========================================================= */\r\n\r\n if (state.metrics.pressure > MAX_PRESSURE && queued.length > 0) {\r\n const worst = queued\r\n .map((t) => ({ t, cost: computeTaskCost(t, state).total }))\r\n .sort((a, b) => b.cost - a.cost)[0].t;\r\n\r\n worst.status = \"failed\";\r\n worst.failureType = \"load_shed\";\r\n worst.failureReason = \"Load shed: system pressure exceeded safe threshold\";\r\n worst.finishedAt = now;\r\n }\r\n\r\n /* =========================================================\r\n 3. ADMISSION CONTROL (concurrency-limited)\r\n ========================================================= */\r\n\r\n const queuedWithCost = state.tasks\r\n .filter((t) => t.status === \"queued\")\r\n .map((t) => ({ t, cost: computeTaskCost(t, state).total }));\r\n\r\n let sortedQueued;\r\n\r\n switch (state.policy) {\r\n case \"THROUGHPUT\":\r\n // favor cheap tasks → maximize completions\r\n sortedQueued = queuedWithCost.sort((a, b) => a.cost - b.cost);\r\n break;\r\n\r\n case \"FAIRNESS\":\r\n // favor oldest tasks\r\n sortedQueued = queuedWithCost.sort(\r\n (a, b) => a.t.createdAt - b.t.createdAt\r\n );\r\n break;\r\n\r\n case \"BALANCED\":\r\n default:\r\n // mix age + cost\r\n sortedQueued = queuedWithCost.sort(\r\n (a, b) =>\r\n 0.5 * (a.cost - b.cost) + 0.5 * (a.t.createdAt - b.t.createdAt)\r\n );\r\n }\r\n\r\n let runningCount = state.tasks.filter((t) => t.status === \"running\").length;\r\n\r\n for (const { t } of sortedQueued) {\r\n if (runningCount >= state.config.maxConcurrentTasks) break;\r\n\r\n t.status = \"running\";\r\n t.startedAt = now;\r\n t.expectedEndAt = now + t.execution.meanDuration;\r\n\r\n t.currentRAM = sampleUsage(t.execution.ramCurve, rng);\r\n\r\n runningCount++;\r\n }\r\n\r\n /* =========================================================\r\n 4. EXECUTE RUNNING TASKS\r\n ========================================================= */\r\n\r\n const running = state.tasks.filter((t) => t.status === \"running\");\r\n\r\n /* ---------- CPU SHARING ---------- */\r\n const cpuTasks = running.filter((t) => t.phase === \"cpu\");\r\n const cpuPerTask =\r\n cpuTasks.length > 0 ? state.resources.totalCPU / cpuTasks.length : 0;\r\n\r\n /* ---------- RAM ACCUMULATION ---------- */\r\n let totalUsedRAM = 0;\r\n for (const t of running) {\r\n if (t.currentRAM !== undefined) {\r\n totalUsedRAM += t.currentRAM;\r\n }\r\n }\r\n\r\n state.metrics.ramPressure = totalUsedRAM / state.resources.totalRAM;\r\n\r\n /* ---------- EXECUTION LOOP ---------- */\r\n for (const t of running) {\r\n const cpuSlow = slowdownFactor(state.metrics.cpuPressure);\r\n\r\n if (t.phase === \"cpu\") {\r\n t.progress +=\r\n ((cpuPerTask / state.resources.totalCPU) *\r\n (dt / t.execution.meanDuration)) /\r\n cpuSlow;\r\n } else {\r\n const ramSlow = 1 + Math.max(0, state.metrics.ramPressure - 1);\r\n\r\n t.progress += (0.3 * dt) / t.execution.meanDuration / ramSlow;\r\n }\r\n\r\n /* ---------- TIMEOUT FAILURE ---------- */\r\n if (t.deadline !== undefined && t.startedAt !== undefined) {\r\n const effectiveDeadline =\r\n t.deadline * Math.max(1, state.metrics.pressure);\r\n\r\n if (now - t.startedAt > effectiveDeadline && state.metrics.pressure > 1) {\r\n t.status = \"failed\";\r\n t.failureType = \"timeout\";\r\n t.failureReason = \"Deadline exceeded under sustained pressure\";\r\n t.finishedAt = now;\r\n continue;\r\n }\r\n }\r\n\r\n /* ---------- PRESSURE-CORRELATED FAILURE ---------- */\r\n const runTime = t.startedAt !== undefined ? now - t.startedAt : 0;\r\n\r\n const fatigueMultiplier = 1 + Math.min(runTime / 10, 1);\r\n\r\n const lambda =\r\n t.failureProbability *\r\n phaseFailureMultiplier(t.phase) *\r\n fatigueMultiplier *\r\n state.metrics.pressure;\r\n\r\n const perTickRisk = 1 - Math.exp(-lambda * dt);\r\n\r\n if (rng() < perTickRisk) {\r\n t.status = \"failed\";\r\n t.failureType = \"pressure\";\r\n t.failureReason = `Execution failure (λ=${lambda.toFixed(3)})`;\r\n t.finishedAt = now;\r\n continue;\r\n }\r\n\r\n /* ---------- COMPLETION ---------- */\r\n if (t.progress >= 1) {\r\n t.status = \"completed\";\r\n t.finishedAt = now;\r\n }\r\n\r\n /* ---------- ASYNC ILLUSION ---------- */\r\n if (rng() < 0.15) {\r\n t.phase = t.phase === \"cpu\" ? \"io\" : \"cpu\";\r\n }\r\n }\r\n\r\n return state;\r\n}\r\n","import { SystemState } from \"../core/state\";\r\nimport { computeMetrics } from \"./metrics\";\r\nimport { schedule } from \"./scheduler\";\r\nimport { RNG } from \"./random\";\r\n\r\nexport function tick(state: SystemState, dt: number, rng: RNG): SystemState {\r\n let next = { ...state, time: state.time + dt };\r\n\r\n next = computeMetrics(next);\r\n next = schedule(next, dt, rng);\r\n next = computeMetrics(next);\r\n\r\n return next;\r\n}\r\n","export type RNG = () => number;\r\n\r\nexport function createRNG(seed: number): RNG {\r\n let t = seed >>> 0;\r\n\r\n return function () {\r\n t += 0x6d2b79f5;\r\n let r = Math.imul(t ^ (t >>> 15), 1 | t);\r\n r ^= r + Math.imul(r ^ (r >>> 7), 61 | r);\r\n return ((r ^ (r >>> 14)) >>> 0) / 4294967296;\r\n };\r\n}\r\n","/// <reference lib=\"webworker\" />\r\nconsole.log(\"🔥 WORKER FILE EXECUTED\");\r\nimport { tick } from \"../engine/tick\";\r\nimport { SystemState } from \"../core/state\";\r\nimport { Task } from \"../core/task\";\r\nimport { PolicyName } from \"../engine/policy\";\r\nimport { SystemResources } from \"../core/resources\";\r\nimport { createRNG } from \"../engine/random\";\r\nlet currentSeed: number = 1;\r\nlet rng = createRNG(currentSeed);\r\n\r\nlet state: SystemState | null = null;\r\nlet interval: ReturnType<typeof setInterval> | null = null;\r\n\r\nconst TICK_MS = 100;\r\nlet sustainedPressureTicks = 0;\r\nconst COLLAPSE_PRESSURE = 1.5;\r\nconst COLLAPSE_TICKS = 10;\r\n\r\nlet eventLog: Array<{\r\n time: number;\r\n message: any;\r\n}> = [];\r\n\r\nself.onmessage = (event: MessageEvent) => {\r\n const msg = event.data;\r\n // Log user actions (but NOT INIT or STATE)\r\n if (state && ![\"STATE\", \"INIT\"].includes(msg.type)) {\r\n eventLog.push({\r\n time: state.time,\r\n message: msg,\r\n });\r\n }\r\n switch (msg.type) {\r\n case \"INIT\": {\r\n state = structuredClone(msg.payload.state);\r\n initialSnapshot = structuredClone(msg.payload.state);\r\n currentSeed = msg.payload.seed ?? 1;\r\n rng = createRNG(currentSeed);\r\n eventLog = [];\r\n sustainedPressureTicks = 0;\r\n post();\r\n break;\r\n }\r\n\r\n case \"START\": {\r\n if (!state || interval !== null) return;\r\n interval = setInterval(runTick, TICK_MS);\r\n break;\r\n }\r\n\r\n case \"PAUSE\": {\r\n if (interval !== null) {\r\n clearInterval(interval);\r\n interval = null;\r\n }\r\n break;\r\n }\r\n\r\n case \"STEP\": {\r\n runTick();\r\n break;\r\n }\r\n case \"SET_CONFIG\": {\r\n if (!state) return;\r\n\r\n state.config = {\r\n ...state.config,\r\n ...msg.payload,\r\n };\r\n\r\n post();\r\n break;\r\n }\r\n case \"ADD_TASK\": {\r\n if (!state) return;\r\n\r\n state.tasks.push({\r\n ...msg.payload,\r\n createdAt: state.time,\r\n });\r\n\r\n break;\r\n }\r\n\r\n case \"SET_POLICY\": {\r\n if (!state) return;\r\n state.policy = msg.payload as PolicyName;\r\n break;\r\n }\r\n\r\n case \"SET_RESOURCES\": {\r\n if (!state) return;\r\n state.resources = {\r\n ...state.resources,\r\n ...(msg.payload as Partial<SystemResources>),\r\n };\r\n for (const w of state.workers) {\r\n w.maxCPU = state.resources.totalCPU;\r\n w.maxRAM = state.resources.totalRAM;\r\n }\r\n post();\r\n break;\r\n }\r\n case \"EXPORT_REPLAY\": {\r\n postMessage({\r\n type: \"REPLAY_DATA\",\r\n payload: {\r\n seed: currentSeed,\r\n events: eventLog,\r\n },\r\n });\r\n break;\r\n }\r\n\r\n case \"REPLAY\": {\r\n if (!initialSnapshot) return;\r\n\r\n // Reset system\r\n state = structuredClone(initialSnapshot);\r\n rng = createRNG(msg.payload.seed);\r\n sustainedPressureTicks = 0;\r\n\r\n // Re-apply events deterministically\r\n for (const e of msg.payload.events) {\r\n applyEvent(e.message);\r\n }\r\n\r\n post();\r\n break;\r\n }\r\n }\r\n};\r\n\r\nfunction runTick() {\r\n if (!state) return;\r\n\r\n state = tick(state, TICK_MS / 1000, rng);\r\n\r\n if (state.metrics.pressure > COLLAPSE_PRESSURE) {\r\n sustainedPressureTicks++;\r\n } else {\r\n sustainedPressureTicks = 0;\r\n }\r\n\r\n if (\r\n state.metrics.stabilityIndex <= 15 ||\r\n sustainedPressureTicks >= COLLAPSE_TICKS\r\n ) {\r\n postMessage({\r\n type: \"COLLAPSE\",\r\n payload: {\r\n time: state.time,\r\n stabilityIndex: state.metrics.stabilityIndex,\r\n pressure: state.metrics.pressure,\r\n reason:\r\n sustainedPressureTicks >= COLLAPSE_TICKS\r\n ? \"Sustained system pressure\"\r\n : \"System stability degraded beyond recovery\",\r\n },\r\n });\r\n\r\n clearInterval(interval!);\r\n interval = null;\r\n return;\r\n }\r\n\r\n post();\r\n}\r\n\r\nfunction post() {\r\n postMessage({\r\n type: \"STATE\",\r\n payload: state,\r\n });\r\n}\r\n\r\nlet initialSnapshot: SystemState | null = null;\r\n\r\nfunction reset() {\r\n if (!initialSnapshot) return;\r\n\r\n state = structuredClone(initialSnapshot);\r\n rng = createRNG(currentSeed);\r\n}\r\n\r\nfunction applyEvent(msg: any) {\r\n switch (msg.type) {\r\n case \"ADD_TASK\":\r\n state?.tasks.push({\r\n ...msg.payload,\r\n createdAt: state.time,\r\n });\r\n break;\r\n\r\n case \"SET_POLICY\":\r\n if (state) state.policy = msg.payload;\r\n break;\r\n\r\n case \"SET_RESOURCES\":\r\n if (state) {\r\n state.resources = {\r\n ...state.resources,\r\n ...msg.payload,\r\n };\r\n }\r\n break;\r\n\r\n case \"START\":\r\n if (!interval) {\r\n interval = setInterval(runTick, TICK_MS);\r\n }\r\n break;\r\n\r\n case \"PAUSE\":\r\n if (interval) {\r\n clearInterval(interval);\r\n interval = null;\r\n }\r\n break;\r\n }\r\n}\r\n"],"mappings":"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","names":["state","state","rng","state","rng","state","rng"]}
package/package.json CHANGED
@@ -1,10 +1,12 @@
1
1
  {
2
2
  "name": "synai-simulator",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
- "files": ["dist"],
7
+ "files": [
8
+ "dist"
9
+ ],
8
10
  "scripts": {
9
11
  "build": "tsup",
10
12
  "dev": "tsup --watch"