openpencil/crates
Kayshen-X 5af1674f6b feat(shell): switch openpencil-shell-web to wasm32-unknown-unknown C-hard pipeline
Lights up the Phase A WebShell on the C-hard pipeline (vendor/skia-
safe-op + crates/wasm-libc-shim, wired in the previous two commits)
so `cargo build --target wasm32-unknown-unknown --features skia`
followed by `wasm-bindgen --target web` produces a browser-loadable
ES module with 0 env.* imports.

What's added:
  - WebBackend (src/backend/mod.rs): impl RenderBackend over a
    skia-safe raster N32_PREMUL surface; presents each frame to the
    host <canvas> via image_snapshot → read_pixels → ImageData →
    put_image_data. end_frame surfaces present errors via
    last_present_error / take_present_error so a stale failure does
    not leak into a subsequent successful frame
  - skia_wasm.rs: thin make_raster_surface helper so swapping in a
    GPU GrContext (Phase A round 2) is a self-contained change
  - mount(canvas_id) entry: locates the host <canvas>, builds a
    WebBackend, paints the Phase A red-rect demo synchronously,
    propagates any present error as a JsValue exception
  - smoke/step-1b.html: manual smoke harness that mounts the shell
    and surfaces a structured diagnostic (with regression-mode
    LinkError messaging + rebuild instructions) if loading fails
  - extern crate wasm_libc_shim as _; in lib.rs to keep the shim's
    no_mangle symbols from being dead-code-eliminated
  - .gitignore for wasm-bindgen pkg/ output

Cargo.toml feature wiring:
  - default = ["web"] keeps the kickoff §1.2 wasm32-clean compile
    guard CI green (stub mount, no skia)
  - skia = ["dep:skia-safe", "wasm-libc-shim"] opts into the real
    WebBackend + raster paint loop; the shim dep is target-gated
    so only wasm32-unknown-unknown actually pulls it in
  - wasm-bindgen = "=0.2.117" pinned (last release that compiles
    on Rust 1.85; bump alongside the toolchain in a future commit)

Verified end-to-end:
  - `cargo build … --features skia --release` green
  - `wasm-bindgen --target web` produces ../pkg/*.{js,_bg.wasm}
  - WebAssembly.Module.imports() returns 22 imports, all from
    ./openpencil_shell_web_bg.js; 0 env.* imports
  - post `wasm-opt -Oz`: 1542 KiB raw / 599 KiB gzip — within
    spec §6 ceiling (≤ 1024 KiB gzip)
  - the kickoff §1.2 wasm32-clean compile guard still passes
    (`cargo check … --no-default-features --features web`)

Browser-side manual smoke (Phase E) is still TODO; the bundle is
structurally LinkError-free but a human still needs to confirm the
red rect actually paints in Safari / Chrome / Firefox before the
sub-phase can be marked complete.

Step 1b §3.2 P0.5B Run path, sub-phase C-hard.2.
2026-05-09 21:08:00 +08:00
..
openpencil-app feat(openpencil-app): skeleton crate (Stage F entry placeholder) 2026-05-03 22:05:00 +08:00
openpencil-shell-core test(shell-core): assert W3C field readback in gesture re-export tests 2026-05-09 21:03:00 +08:00
openpencil-shell-native fix(shell): drop orphan pub mod event refs after Step 1b §3.2 merge 2026-05-08 22:35:00 +08:00
openpencil-shell-web feat(shell): switch openpencil-shell-web to wasm32-unknown-unknown C-hard pipeline 2026-05-09 21:08:00 +08:00
pen-codegen chore(workspace): cargo-deny 0.18 activation (Phase 1 Task 1.8 Step 6) 2026-05-03 23:05:00 +08:00
pen-core chore(workspace): cargo-deny 0.18 activation (Phase 1 Task 1.8 Step 6) 2026-05-03 23:05:00 +08:00
pen-engine chore(workspace): cargo-deny 0.18 activation (Phase 1 Task 1.8 Step 6) 2026-05-03 23:05:00 +08:00
pen-figma chore(workspace): cargo-deny 0.18 activation (Phase 1 Task 1.8 Step 6) 2026-05-03 23:05:00 +08:00
pen-types feat(pen-types): skeleton crate (bucket A) 2026-05-03 22:35:00 +08:00
wasm-libc-shim feat(shell): add wasm-libc-shim crate for wasm32-unknown-unknown skia bundle 2026-05-09 21:07:00 +08:00