Skip to content

Release Plan & Roadmap #12

Description

@gonzalocasas

Release Plan and Post-1.0 Roadmap

This document is now the working roadmap for the released
@compas-dev/compas-threejs-ts package.

Current status

Last reviewed: 2026-08-14

  • v1.0.0 was published on 2026-08-13.
  • v1.0.1 is the current release on main; it made npm publication retryable.
  • The repository is owned by compas-dev and the package is published as
    @compas-dev/compas-threejs-ts.
  • Release Please creates release pull requests and GitHub releases. GitHub
    Actions publishes to npm with Trusted Publishing and provenance.
  • The sibling Python package remains a first-class consumer of the standalone
    build and must continue to work without Node.js at installation or runtime.

Remote follow-up work exists on these branches and should be reviewed before
reimplementing the same features:

  • origin/feature/spinner
  • origin/feature/object-visibility
  • origin/feature/object-actions-panel

Their status relative to main is a dated observation, not a guarantee that a
pull request is still open.

What shipped in 1.0

The completed release work can be summarized as follows:

  • A side-effect-free, instance-based createViewer API with embedded and
    WebSocket modes, explicit dispatch, reset, resize, and dispose
    lifecycle methods, typed errors, host callbacks, and multi-instance support.
  • Separate ESM library and standalone application builds, curated TypeScript
    declarations and exports, explicit CSS, restrictive package contents, clean
    consumer installation tests, and self-hosted UI fonts.
  • Binary Python-to-browser COMPAS Protobuf dispatch and JSON browser-to-Python
    callbacks, with Python-generated compatibility fixtures and deliberate errors
    for unsupported or invalid messages.
  • The documented 1.0 rendering set: Box, Capsule, Circle, Cone, Cylinder,
    Frame, Line, Mesh, Plane, Point, Pointcloud, Polyhedron, Polyline, Sphere,
    Torus, and Vector. Python Breps use the view-mesh path.
  • Materials, lights, scene controls, themes, UI controls, text tags, metadata,
    object actions, visibility commands, picking, and the embedded kitchen-sink
    example, subject to the limits recorded in docs/support-matrix.md.
  • Effective strict TypeScript, ESLint, Prettier, unit, compatibility, build,
    packed-package, production-audit, and Chromium browser gates in CI.
  • Public metadata, MIT licensing, compatibility and dependency policies,
    changelog, release instructions, automated GitHub releases, and npm
    publication through a protected environment.
  • Cross-repository fixes for the Python compas_pb >=1,<2 constraint, its test
    task, and the default PhysicalMaterial.attenuation_distance wire value.

The old stacked-PR instructions, rewritten commit SHAs, pre-release gates, and
completed audit narratives have been removed. Consult git log, the tagged
releases, and CHANGELOG.md when historical detail is needed.

What's left: quick outline

  1. Integrate the existing spinner, object-visibility, and object-actions UI
    follow-ups and release them through the normal 1.x workflow.
  2. Finish or explicitly narrow the limited command surface: text geometry,
    Sky, sunlight, RectAreaLight, advanced physical materials, and exact Python
    command parity.
  3. Harden the shipped geometry, lifecycle, resource ownership, and UI behavior
    with focused correctness and regression tests.
  4. Harden WebSocket and untrusted-input handling, then expand browser and
    security coverage.
  5. Build the public documentation site and add the missing contributor and
    security policies.
  6. Add deferred geometry and Graph support incrementally after their contracts
    are designed and tested.
  7. Maintain compatibility, dependencies, release automation, and the sibling
    Python/VS Code integrations across future 1.x releases.

Detailed plan

1. Integrate the active UI follow-ups

Treat the existing remote branches as review inputs. Rebase or update them from
current main; do not reproduce their changes from memory.

  • Review feature/spinner for command validation, accessibility, repeated
    show/update/hide behavior, disposal, and Python-generated payload tests.
  • Review feature/object-visibility for hidden-object picking, reset,
    replacement, removal, show-all behavior, and keyboard accessibility.
  • Review feature/object-actions-panel for selection changes, empty state,
    callback values, narrow layouts, and interaction with ObjectInfo.
  • Resolve overlapping layout/store changes deliberately if the branches are
    combined or merged in sequence.
  • Update the support matrix and changelog to describe the release in which
    each feature actually ships. Do not retroactively imply that a post-1.0.0
    feature was present in the original tarball.
  • Rebuild and review the sibling Python frontend assets in a separate,
    explicit cross-repository change when a standalone feature is merged.

Acceptance criteria:

  • Each command has positive, malformed-input, replacement, reset, and disposal
    coverage appropriate to its state.
  • Embedded mode and the Python WebSocket application behave consistently.
  • npm run check, npm run test:package, and npm run test:browser pass.
  • The resulting version is released only through Release Please and CI.

2. Complete the limited command and protocol surface

Python command parity

  • Generate deterministic Python fixtures for every material, light, scene,
    UI, text, tag, metadata, object-action, visibility, and spinner variant.
  • Decode and validate those fixtures in TypeScript. Keep the Python
    producer, TypeScript discriminated union, validator, handler, tests, and
    protocol documentation synchronized.
  • Constrain Python Selection.options and default_value to the contract
    expected by the TypeScript select command, or widen the browser contract
    deliberately and test the chosen behavior.
  • Correct the live Python public parameter spellings
    clearcot_roughness and iridescenceior through a documented deprecation
    path rather than an abrupt breaking change.
  • Add TypeScript-to-Python callback fixtures for UI, picking, object actions,
    loaded JSON, and custom host messages.

The earlier default-PhysicalMaterial blocker is resolved: Python now omits an
unspecified attenuation distance and rejects non-finite explicit values. Keep
that behavior covered on both sides.

Text geometry

  • Decide whether typeface JSON files are bundled, resolved from Three.js,
    or supplied through a configurable public asset base URL.
  • Ensure both the npm library and Python standalone build resolve assets
    without assuming the host root is /.
  • Validate font name, weight, text length, direction/up vectors, and
    degenerate bases.
  • Test successful loading, caching, failure reporting, replacement, reset,
    and disposal. Only then move text geometry out of “limited”.

The bundled Inter WOFF2 file solves the viewer UI font and offline-privacy
problem; it does not supply the Three.js typeface JSON needed by text geometry.

Materials and lights

  • Replace the duplicated parseColor/parseInt helpers with a single
    validated Three.js color conversion and cover valid and invalid forms.
  • Verify all physical-material fields against current Three.js semantics,
    including ranges and optional values.
  • Make Sky elevation and azimuth drive its companion lights instead of
    creating hard-coded white lights at the world origin.
  • Add directional-light targets to the scene graph so sunlight direction is
    honored.
  • Verify the current Three.js setup requirements and rendering behavior for
    RectAreaLight, then initialize or defer it explicitly.
  • Add conversion, replacement, and cleanup tests for every advertised
    material and light variant.

Acceptance criteria:

  • Every public Python command has an exact wire fixture and one explicit status:
    supported, limited with documented constraints, or unsupported.
  • Invalid payloads report stable errors without partially mutating viewer state.
  • The support matrix no longer groups unverified variants under broad claims
    such as “basic materials and lights”.

3. Certify and harden the shipped rendering set

Keep the 1.0 geometry boundary stable while improving confidence. Do not mix new
geometry types into these hardening slices.

  • Add table-driven converter tests for every shipped geometry and helper,
    including non-axis-aligned frames and non-origin positions.
  • Confirm the matrix element ordering in matrixFromElements against a
    Python-generated, non-symmetric transform fixture.
  • Validate missing frame members, empty point sets, zero-length vectors,
    parallel frame axes, non-finite coordinates, and malformed dimensions.
  • Test mesh/polyhedron index bounds, degenerate faces, fan-triangulation
    limitations, normals, and upstream-triangulation guidance.
  • Test the documented display semantics: Circle as a filled disc, Plane as
    a finite surface, and Frame/Vector as helpers.
  • Exercise replacement, assigned-material reuse, edge helpers, visibility,
    picking, removal, reset, and disposal for every object category.
  • Add small visual-regression scenes for representative solids, curves,
    helpers, points, and datastructures.

Acceptance criteria:

  • Every type listed as included has positive, invalid-input, orientation,
    replacement, and cleanup coverage where applicable.
  • Renderer failures are deterministic CompasViewerErrors and do not corrupt
    existing scene state.
  • The support matrix states known approximations and triangulation limits.

4. Finish lifecycle, ownership, and UI correctness

  • Separate CSS2D text-tag ownership from the geometry registry so GUID
    collisions cannot silently replace unrelated objects; remove their DOM
    elements on replacement and reset.
  • Dispose TransformControls, its helper resources, axes helpers, default
    lights, and every viewer-owned material exactly once.
  • Define shared-versus-owned material rules so replacing or removing one
    object never disposes a material still used by another.
  • Repair transform-button activation events and active styling; cover mouse
    and keyboard mode changes.
  • Reuse the text-input shortcut guard in the runtime-level p, i, and
    Escape handler.
  • Replace timestamp-only saved-view identifiers or otherwise prevent rapid
    collisions.
  • Remove the remaining obsolete aliases, comments, duplicated helpers, and
    release-number TODO labels after their behavior is covered.

Acceptance criteria:

  • Repeated create/reset/dispose and replacement loops leave no listeners,
    render loops, DOM labels, scene objects, or owned GPU resources behind.
  • Two viewers remain independent under all tested UI and lifecycle actions.
  • Keyboard shortcuts never fire while editing an input, select, textarea, or
    content-editable element.

5. Harden transport and untrusted input

  • Validate WebSocket host, port, workspace, and secure-mode inputs before
    constructing the URL.
  • Catch synchronous constructor failures on initial and retry attempts.
  • Replace fixed unbounded retries with documented backoff/cancellation and
    controlled-timer tests.
  • Decide whether embedded library consumers may inherit WebSocket settings
    from the host page query string; make the precedence explicit.
  • Test binary receive, ignored text receive, JSON callback send, clean
    shutdown, named workspaces, and Python state replay.
  • Add depth, object-count, and payload-size limits to recursive dispatch.
  • Replace or formally constrain the generic bytes instanceof Uint8Array
    geometry heuristic.
  • Bound loaded JSON size and shape before sending it to a host.
  • Validate semantic ranges, collection sizes, and degeneracy in addition to
    primitive field types.
  • Review text, labels, colors, URLs, and UI values for HTML/script injection
    and uncontrolled browser resource allocation.

Acceptance criteria:

  • Malformed or hostile input is bounded, produces a useful error, and leaves
    connection and scene state valid.
  • Retry and shutdown tests use controlled timers and never depend on wall-clock
    sleeps.
  • Python reconnect/replay behavior is deterministic and idempotent.

6. Expand tests, compatibility, and CI

The current CI covers Node 22, strict checks, a production audit, a clean packed
consumer, and Chromium Playwright. Extend it where the support policy is broader
than the gate.

  • Run browser integration tests in Firefox and WebKit, or narrow the stated
    browser policy until those engines are continuously tested.
  • Test the documented minimum Node version and the supported Three.js range.
  • Add coverage thresholds after dispatcher/lifecycle/command tests are
    representative; prioritize complete public-boundary coverage over a broad
    repository percentage.
  • Fail browser tests on unexpected console errors and warnings.
  • Establish package, bundle, source-map, and startup-performance budgets.
  • Add grouped automated dependency updates and keep production audit policy
    explicit.
  • Mechanically verify that curated public.d.ts declarations match the
    runtime exports, or replace the manual copy with generated declarations.

Acceptance criteria:

  • Every compatibility promise is exercised in CI or explicitly documented as
    manually verified.
  • Packed-tarball tests cover runtime exports, declarations, CSS/assets, and a
    real bundler consumer without repository aliases.

7. Publish complete public documentation and governance

The baseline README, compatibility policy, support matrix, dependency policy,
changelog, and release guide exist. Build the broader documentation only from
contracts established by the preceding slices.

  • Add VitePress for the site and TypeDoc with
    typedoc-plugin-markdown for the small public API reference.
  • Decide whether the TypeScript library has its own site or a section of the
    Python documentation, and designate one canonical protocol reference.
  • Document installation, standalone use, embedded use, WebSocket options,
    commands, lifecycle, errors, assets, browser support, and troubleshooting.
  • Add complete Vite and non-Vite consumer examples using the packed package.
  • Publish documentation through GitHub Pages and test examples against the
    released package.
  • Add CONTRIBUTING.md with architecture, setup, validation, generated
    assets, and pull-request guidance.
  • Add SECURITY.md with supported versions and private-reporting guidance.
  • Add contribution templates and a code of conduct if required by the
    organization.
  • Document semantic-versioning, deprecation, support, and emergency npm
    deprecation/yank policies.

Acceptance criteria:

  • A new npm consumer can install, create, configure, use, and dispose a viewer
    without reading source code.
  • Protocol behavior is documented once and linked from the Python and
    TypeScript projects without contradictory copies.

8. Add post-1.0 geometry and Graph support

Each addition is a normal backward-compatible feature release with design,
Python fixtures, TypeScript tests, browser coverage, documentation, and a
changelog entry. A source placeholder is not an implementation.

Geometry candidates:

  • Arc
  • Bezier
  • Ellipse
  • Hyperbola
  • Parabola
  • Polygon
  • PolyhedronFace and MeshFaceList only if they become meaningful top-level
    viewer objects
  • Decide whether Quaternion, Rotation, and Translation need visualizations
    or remain non-renderable mathematical data.

For curve and surface additions:

  • Define sampling tolerances and configurable resolution.
  • Use robust triangulation for non-convex polygonal faces.
  • Normalize or reject invalid frames and transforms.
  • Add positive, invalid, orientation, replacement, material, picking, and
    cleanup coverage before changing the support matrix.

Graph support:

  • Study COMPAS core's GraphSceneObject/compas.scene.GraphObject
    behavior and define the intended viewer contract.
  • Decide whether the viewer consumes a Graph wrapper, an explicit scene
    representation, or node/edge geometry messages.
  • Define node/edge IDs, styling, visibility, picking, metadata, actions,
    incremental updates, and removal.
  • Implement Graph rendering without coupling the public TypeScript API to a
    Python-only scene-object implementation.
  • Add Python fixtures, interaction and cleanup tests, documentation, and a
    representative example.

Acceptance criteria:

  • A new type appears as supported only after its public semantics and failure
    behavior are documented and tested.
  • Additions do not break the stable 1.x viewer API, transport, or lifecycle.

9. Ongoing release and integration maintenance

  • Monitor npm and GitHub advisories and review dependency updates in focused
    groups.
  • Test new compas-pb-ts, compas_pb, Three.js, Vue, TypeScript, Node, and
    browser releases before widening declared ranges.
  • Keep versioned cross-language fixtures for every supported wire version.
  • Verify provenance, tarball contents, public quick starts, and npm install
    after every release.
  • Update the Python static assets only from a reviewed frontend commit and
    keep that destructive replacement as a separate diff.
  • Update the VS Code extension to and test it against the public
    instance-based API; do not restore window.compasViewer.
  • Define issue-response, backport, and supported-release policies when more
    than one line needs maintenance.
  • Deprecate public APIs through documented releases rather than silent
    changes.

Working discipline

  • Start new work from current main; inspect active branches before duplicating
    work.

  • Keep changes reviewable: protocol changes, generated Python assets,
    mechanical formatting, and release automation should be separate commits.

  • For Python-to-browser changes, inspect the Python producer and add an exact
    payload fixture. For browser-to-Python changes, inspect the Python inbox and
    add a joint callback test.

  • Run both the npm library and standalone application paths. A green library
    build alone does not protect the Python consumer.

  • The standard TypeScript verification set is:

    npm run check
    npm run audit:prod
    npm run test:package
    npm run test:browser
    git diff --check
  • Run the sibling Python suite for coordinated protocol or asset changes.

  • sync_frontend deletes and replaces the packaged frontend directory. Inspect
    exact paths first and review the generated asset diff separately.

  • Never run a checker against the root tsconfig.json without --build; it
    contains project references and no root files. Use npm run typecheck.

  • Release through conventional commits, Release Please, and the protected npm
    environment. Do not publish stable versions from a workstation.

Definition of done for a post-1.0 slice

A slice is complete when:

  • Its public behavior and unsupported cases are explicit.
  • Unit, compatibility, browser, packed-package, and Python tests have been added
    in proportion to the change.
  • Resource ownership and reset/disposal behavior are covered.
  • The support matrix, API/protocol documentation, and changelog are consistent.
  • All relevant CI-equivalent checks pass from a clean dependency installation.
  • Cross-repository generated assets and integration changes are reviewed
    separately.
  • Publication, when needed, is reproducible from the tagged main commit.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions