Skip to main content

brep_app/
lib.rs

1//! Shared eframe application for native windows and WebAssembly canvases.
2//! [`app::BrepApp`] hosts the renderer and egui in one wgpu frame.
3
4pub mod app;
5pub mod automation;
6mod color;
7pub mod column_tree;
8pub mod diagnostics;
9pub mod document;
10/// The three document classes (`.nbrep` / `.fbrep` / `.tbrep`, plm-build-spec §3.1).
11pub mod document_class;
12/// A family seed's table and its Generate (`.fbrep`, plm-build-spec §3.2).
13pub mod family_table;
14/// Register this build as the system's `.nbrep` opener
15/// (`brep-app --install-file-associations`). Native only: the browser has no
16/// file association to claim.
17#[cfg(not(target_arch = "wasm32"))]
18pub mod file_association;
19pub mod fonts;
20pub mod form;
21pub mod form_view;
22pub mod icon_text;
23pub mod icons;
24mod http;
25/// The native binary's `log` sink (`main.rs`): `RUST_LOG` to stderr. Replaces
26/// `env_logger`; the wasm build logs through the browser console instead.
27#[cfg(not(target_arch = "wasm32"))]
28pub mod logger;
29/// The embedded MCP server (`brep-app --mcp`); native builds with `mcp`.
30#[cfg(all(not(target_arch = "wasm32"), feature = "mcp"))]
31pub mod mcp;
32pub mod offsite;
33pub mod palette;
34pub mod panels;
35/// Where a frame's milliseconds go — the per-frame timing record behind the
36/// `__brepPerf` blob and the Info window's Performance rows.
37pub mod perf;
38/// The PLM client: config, transport, sign-in and the PLM store backend. Inert
39/// with no server configured.
40pub mod plm;
41pub mod recovery;
42/// Scripts in the CAD app: the CAD host for the PLM's interpreter core (S11).
43#[cfg(feature = "scripting")]
44pub mod scripting;
45pub mod store;
46/// A template's input marks and its spin-out (`.tbrep`, plm-build-spec §3.1).
47pub mod template;
48pub mod viewport;
49pub mod workbench;
50
51
52// The wasm history runner: a dedicated web worker so a history run stays OFF the
53// browser main thread (single-threaded wasm) and the UI never freezes during a run.
54// Its `worker_entry` is the worker-side onmessage loop. wasm only.
55#[cfg(target_arch = "wasm32")]
56pub mod worker;
57
58// --- wasm entry ----------------------------------------------------------------
59#[cfg(target_arch = "wasm32")]
60mod web {
61    use wasm_bindgen::prelude::*;
62    use wasm_bindgen::JsCast;
63
64    /// Start the eframe app on the given `<canvas>` element id. Called from JS.
65    #[wasm_bindgen]
66    pub async fn start(canvas_id: String) -> Result<(), JsValue> {
67        brep_render::brep_kernel::panic_hook::set_once();
68
69        // Bring up browser persistence FIRST. `ModelStore` is synchronous but every
70        // browser store large enough for a native BREP payload is async, so the
71        // whole key space is pulled into an in-memory mirror here — inside the one
72        // async seam the app has — BEFORE `BrepApp::new` performs its first read.
73        // See store.rs `mirror_store`.
74        crate::store::hydrate_web_store().await;
75
76        let document = web_sys::window()
77            .ok_or_else(|| JsValue::from_str("no window"))?
78            .document()
79            .ok_or_else(|| JsValue::from_str("no document"))?;
80        let canvas = document
81            .get_element_by_id(&canvas_id)
82            .ok_or_else(|| JsValue::from_str("canvas element not found"))?
83            .dyn_into::<web_sys::HtmlCanvasElement>()
84            .map_err(|_| JsValue::from_str("element is not a <canvas>"))?;
85
86        eframe::WebRunner::new()
87            .start(
88                canvas,
89                eframe::WebOptions::default(),
90                Box::new(|cc| {
91                    crate::fonts::install(&cc.egui_ctx);
92                    crate::app::BrepApp::new(cc)
93                        .map(|app| Box::new(app) as Box<dyn eframe::App>)
94                        .map_err(|e| e.into())
95                }),
96            )
97            .await
98    }
99}