Make machine configuration authoritative and restore native checkpoints exactly
This commit is contained in:
34
web/workspace/web-settings.mjs
Normal file
34
web/workspace/web-settings.mjs
Normal file
@@ -0,0 +1,34 @@
|
||||
import values from "./web-settings.json" with { type: "json" };
|
||||
|
||||
function freeze(value) {
|
||||
if (value && typeof value === "object") { Object.values(value).forEach(freeze); Object.freeze(value); }
|
||||
return value;
|
||||
}
|
||||
function finitePositive(value, name) {
|
||||
if (!Number.isFinite(value) || value <= 0) throw new Error(`web_settings_invalid:${name}`);
|
||||
}
|
||||
for (const [name, value] of Object.entries(values.runtime.planner)) if (name !== "blend") finitePositive(value, `planner.${name}`);
|
||||
for (const [name, value] of Object.entries(values.runtime.io)) {
|
||||
if (name === "spindle_tolerance") {
|
||||
if (!Number.isFinite(value) || value < 0) throw new Error("web_settings_invalid:io.spindle_tolerance");
|
||||
} else finitePositive(value, `io.${name}`);
|
||||
}
|
||||
for (const [name, value] of Object.entries(values.viewer.camera)) finitePositive(value, `camera.${name}`);
|
||||
finitePositive(values.viewer.mm_scale, "mm_scale");
|
||||
finitePositive(values.viewer.pixel_ratio_limit, "pixel_ratio_limit");
|
||||
for (const key of ["poll_ms", "jog_cycles", "run_cycles", "preview_progress_ms", "zoom", "zoom_min", "zoom_max", "zoom_step"]) finitePositive(values.ui[key], key);
|
||||
finitePositive(values.ui.override_debounce_ms, "override_debounce_ms");
|
||||
if (!(values.ui.motion_scale_min > 0 && values.ui.motion_scale_min <= 1)) throw new Error("web_settings_invalid:motion_scale_min");
|
||||
if (!values.ui.jog_increments.every((value) => Number.isFinite(Number(value)) && Number(value) > 0)) throw new Error("web_settings_invalid:jog_increments");
|
||||
if (values.ui.zoom_min > values.ui.zoom_max || values.ui.zoom < values.ui.zoom_min || values.ui.zoom > values.ui.zoom_max) throw new Error("web_settings_invalid:zoom_range");
|
||||
if (!["x", "y", "y2", "z", "z2", "p"].includes(values.ui.initial_view)) throw new Error("web_settings_invalid:initial_view");
|
||||
for (const key of ["jog_cycles", "run_cycles"]) if (!Number.isSafeInteger(values.ui[key])) throw new Error(`web_settings_invalid:${key}`);
|
||||
if (values.viewer.camera.near >= values.viewer.camera.far || values.viewer.camera.min_distance >= values.viewer.camera.max_distance) throw new Error("web_settings_invalid:camera_range");
|
||||
for (const model of Object.values(values.viewer.models)) finitePositive(model.datum_z_mm, "model_datum");
|
||||
if (values.runtime.planner.max_feed_override < 1) throw new Error("web_settings_invalid:feed_limit");
|
||||
for (const key of ["spindle_count", "tool_capacity", "encoder_count"]) if (!Number.isSafeInteger(values.runtime.io[key])) throw new Error(`web_settings_invalid:io.${key}`);
|
||||
export const WEB_SETTINGS = freeze(values);
|
||||
|
||||
export function axisImagePath(name, base = ".") {
|
||||
return `${base.replace(/\/$/, "")}/${WEB_SETTINGS.assets.axis_images}/${name}`;
|
||||
}
|
||||
Reference in New Issue
Block a user