imrishabh18/rp2040-motor-controller

This circuit module provides a microcontroller-based NEMA17 stepper motor driver with integrated USB-C Power Delivery, temperature sensing, and safety interlocks.

Version
1.0.16
License
unset
Stars
0

routing/saved-routing.ts

import plan from "./route-plan.json";

/** A fixed routing solution through tscircuit's local algorithmFn interface.
 * No check is suppressed: core regenerates traces, vias, pours and DRC normally.
 * Refuse stale geometry/connectivity instead of applying routes to an edited PCB.
 */
export function canonicalRoutingInput(value: unknown): string {
  const normalize = (item: any): any => {
    if (typeof item === "number") return Math.round(item * 1e8) / 1e8;
    if (Array.isArray(item)) return item.map(normalize);
    if (item && typeof item === "object") return Object.fromEntries(
      Object.keys(item).sort().map(key => [key, normalize(item[key])]),
    );
    return item;
  };
  return JSON.stringify(normalize(value));
}

const expected = canonicalRoutingInput(plan.expectedInput);

export const savedRouting = async (input: unknown) => {
  if (canonicalRoutingInput(input) !== expected) {
    const actual = JSON.parse(canonicalRoutingInput(input));
    const wanted = JSON.parse(expected);
    const diffs: string[] = [];
    const compare = (a: any, b: any, path: string) => {
      if (JSON.stringify(a) === JSON.stringify(b) || diffs.length >= 8) return;
      if (a && b && typeof a === "object" && typeof b === "object") {
        for (const key of new Set([...Object.keys(a), ...Object.keys(b)])) compare(a[key], b[key], `${path}.${key}`);
      } else diffs.push(`${path}: expected ${JSON.stringify(b)}, got ${JSON.stringify(a)}`);
    };
    compare(actual, wanted, "input");
    throw new Error("Regenerate and validate routing/route-plan.json. Routing input mismatch: " + diffs.join("; "));
  }
  const listeners = new Map<string, Array<(event: any) => void>>();
  return {
    on(name: string, callback: (event: any) => void) {
      listeners.set(name, [...listeners.get(name) ?? [], callback]);
    },
    start() {
      const event = { traces: structuredClone(plan.traces) };
      for (const callback of listeners.get("complete") ?? []) callback(event);
    },
    stop() {},
  };
};