Skip to content

Node.js

Works in Node 18+ and modern browsers.

Minimal client

// cnw.js
const ENDPOINT = process.env.CNW_ENDPOINT || "https://api.cutweaver.io";
const API_KEY = process.env.CNW_API_KEY;

export async function solve(payload) {
  const res = await fetch(`${ENDPOINT}/api/v1/solve`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      ...(API_KEY ? { "X-API-Key": API_KEY } : {}),
    },
    body: JSON.stringify(payload),
  });

  const data = await res.json();
  if (!data.ok) {
    const err = new Error(data.error?.message ?? "CutWeaver error");
    err.code = data.error?.code;
    err.status = res.status;
    throw err;
  }

  return data;
}

Usage

import { solve } from "./cnw.js";

const response = await solve({
  sheets: [
    { width: 3210, height: 2250, quantity: 1, kerfWidth: 4 },
  ],
  pieces: [
    { originalIndex: 0, width: 800, height: 600, quantity: 4, canRotate: true },
    { originalIndex: 1, width: 1200, height: 900, quantity: 2, canRotate: true },
  ],
  params: { kerfWidth: 4 },
  strategy: "greedy",
});

const { result } = response;
console.log(`Placed: ${result.totalPlaced}`);
for (const sheet of result.sheets) {
  console.log(`Sheet ${sheet.sheetIndex}: ${(sheet.utilization * 100).toFixed(1)}%`);
}

Retry on 429 / 5xx

async function solveWithRetry(payload, { maxAttempts = 3 } = {}) {
  let lastErr;
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    try {
      return await solve(payload);
    } catch (e) {
      lastErr = e;
      if (e.status !== 429 && e.status < 500) throw e;
      await new Promise((resolve) => setTimeout(resolve, 2 ** attempt * 500));
    }
  }
  throw lastErr;
}