1.2.0
Release Notes v1.2.0
This release is about making the library honest and reliable: every CAD package is now compiled under the full TypeScript strict set, the test suites moved to Vitest with real assertions and a coverage floor, and the public API surface of every package is pinned with API Extractor reports. That work surfaced and fixed a long list of real defects - in cameras, drawing, colours, splitting, imports and worker dispatch - that the previous typings had been hiding. On top of that: a rebuilt draw entity model with proper result types, a generated worker API layer held in step with the kernel, and the Verb NURBS API is deprecated ahead of its removal in the next major.
If you consume the packages from TypeScript, expect better types, fewer anys and a few corrected behaviours listed below.
Type safety & API surface
Full strict mode across all packages
- All thirteen packages compile with
strict,noUncheckedIndexedAccess,exactOptionalPropertyTypes,noUnusedLocalsandnoUnusedParameters. Optional inputs are now spelledT | undefined, so a strict consumer can pass optional values straight through. genericCallToWorkerPromiseis generic (<T = unknown>), so a worker call's declared return type is the type you get instead ofPromise<any>.- JSCAD entities are typed:
JSCADEntityis nowJSCADGeom2 | JSCADGeom3 | JSCADPath2(structural mirrors of@jscad/modeling), no longerany.asSolid/asPath/asRegionname the operation and what arrived when a kind mismatches. - JSON API inputs are
unknowninstead ofany; returns keepanydeliberately (the caller knows the shape). - The public API of every package is pinned in
etc/<package>.api.md; a surface change is now a reviewed diff.
A real entity model for draw
bitbybit.draw.drawAnyAsync/drawAnyresolve their result from what you passed: a shape gives the engine scene object, a tag gives a tag, an empty list givesundefined(Draw.Drawn<E, T>,DrawnEntity). No more narrowing a four-arm union or asserting throughunknown.- Entity detection is one ordered table shared by all three renderers (it was three hand-copied chains that had drifted apart), and
drawingTypesis a string enum with identical membership everywhere. - JSCAD
Path2now has its own draw handler - it used to fall through to the 3D polyline path and draw the wrong thing. Its accumulated transforms are applied. - Manifold pointers carry a literal type tag, as OCCT pointers already did.
Deprecations
bitbybit.verb.*(curves, surfaces, intersections) is deprecated and will be removed in the next major. Verbnurbs has not been maintained upstream since 2022 and ships no usable typings. Drawing does not depend on it - anything with atessellatestill draws.bitbybit.jscad.polygon.createFromCurveis deprecated with it.
Fixes
Geometry (OCCT, Manifold, JSCAD)
bitbybit.manifold.booleans.splitByPlaneOnOffsetswas discarding the remainder after the last cut:noffsets gavenpieces and lost the rest. It now returnsn + 1pieces and the whole solid is accounted for; a solid entirely before an offset comes back whole.- Manifold from polygon points rebuilds vertex identity on a tolerance grid instead of exact equality, so closed geometry touched by floating-point arithmetic no longer fails with "Not manifold".
- STEP / IGES readers now check the transferred shape as well as the reader status - a file that parses but yields no model returns nothing instead of a null shape.
- List-variant fillets and chamfers and
wire.fromPointsthrow a clear error on mismatched lists or fewer than two points instead of silently returningundefined. - A failed STEP transfer rethrew a bare object (
[object Object]); it throws a properErrorwith the message andcause. - SVG import: elements that are neither drawn nor deliberately skipped (
use,text,image,foreignObject, ...) now produce a warning per tag, with advice, instead of an empty scene. - Worker parity: several worker paths dispatched to kernel methods that did not exist or with DTO fields the kernel never read (
assembly.manager.deleteDocument,setDocLabelColor,setDocLabelName,hull,fromBaseLineson edges and wires,vertexToPoint, manifoldscale, meshevaluatetransform) - all now work. A parity check pins the two layers together. Vector.removeAllDuplicateVectorsis indexed rather than quadratic: 80 000 points went from ~11.5 s to ~30 ms with identical results.
Rendering (BabylonJS, ThreeJS, PlayCanvas)
- Polyline colours: a polyline's own colour no longer repaints every polyline that had none (JSCAD geometry with baked colours rendered wrongly in all three engines; PlayCanvas ignored per-polyline colours entirely).
- Redraw leaks:
drawSurfacesMultiColour(Babylon) and polyline groups (ThreeJS) orphaned a container on every update; updates now reuse the instance you pass in. - Drawing a closed JSCAD path no longer appends a point to your own geometry, and the closing segment stays in the path's plane.
shapeToMeshnow actually fills thenormalsarray it always declared.- Colour components outside 0-1 are clamped and reported instead of producing an invalid hex string.
- BabylonJS:
arcRotate.createno longer flips negative alpha/beta;camera.getSpeedreturns a number (it returned the target);mesh.createMeshInstanceAndTransformused radians for meshes with children and degrees for those without - degrees everywhere now;gaussianSplatting.getSplatPositionsread the wrong stride and mixed splat coordinates;enablePointerMoveEventswithincludeChildrendisabled the children;targetCamera.createnamed every camera "freeCamera";exportMeshesToStlpushed into a list that was never created;clearAllDrawnno longer leaves anullin the scene's transform nodes. - ThreeJS: the animation loop now measures the real frame delta instead of assuming 1/60 s, so camera inertia and
onRenderintegration run at the correct speed on 120 Hz and 30 Hz displays (clamped to 0.1 s). Lines are never drawn thinner than a pixel. - PlayCanvas: drawing a tag threw on every call; two-sided and back-face colour options were read from the wrong place.
Tooling, packaging & docs
- Packages are one pnpm workspace with exact pins; each package declares the dependencies it actually imports (
verb-nurbs-web,jsonpath-plus,rxjs,@bitbybit-dev/baseand the workers are explicit now instead of hoisted). - The three OCCT WASM kernels are no longer tracked in git -
packages/dev/occt/kernels.jsonnames each variant with its size and SHA-256, andnpm run kernels:fetchdownloads and verifies them. The@bitbybit-dev/occttarball ships aNOTICEand the OCCT and Draco license texts. - The worker API layer is generated from the kernel and the OCCT inputs are authored as fragments assembled into one namespace; the build order is derived from the package manifests (
tsc -b). - Packages are published with npm trusted publishing (OIDC); prereleases go to their own dist-tag.
@bitbybit-dev/cad-cloud-sdktypes regenerated from the current OpenAPI document, with a version check before publish;./package.jsonis exposed from its exports map.@bitbybit-dev/create-appfails loudly if the kernel-architecture patch does not match the template, instead of scaffolding a kernel you did not choose.- Examples: every example is verified on its own and weekly; Create React App examples moved to Vite; high advisories cleared from every example lockfile.
- Docs: the TypeScript API reference is now at https://docs.bitbybit.dev and linked from every package README; learn.bitbybit.dev SEO audit fixes; Docusaurus 3.7 -> 3.10; AI context files (
llms.txt) are published beside the release assets. - Dependabot enabled and a GitHub Advisory Database check gates the tree; a nightly workflow runs the Node version matrix.
Dependencies
- Engine versions are unchanged in this release: BabylonJS 9.13, ThreeJS 0.185.0, PlayCanvas 2.20.0, Manifold 3.3.2, JSCAD modeling 2.12.3.
- OCCT kernel builds are unchanged from v1.1.1.
- Development tooling: Jest -> Vitest 4, ESLint 10, TypeScript 5.9.3, pnpm 11.