Skip to content

Back to Releases

ivue@2.5.0 — definePropTypes, the Static re-wrap fix, private banned ​

View on GitHub ↗Released August 31, 2026

Feature release, zero breaking runtime changes. Three stories: the props-contract system gets its missing piece (definePropTypes, and defaults maps that no longer need Omit), Static() fixes a re-wrap bug in deep subclass chains, and the shipped standard hardens — every override says override, private is banned, and a runnable gate enforces the rules in CI.

Added ​

  • definePropTypes(types) — an identity helper for prop-TYPES maps. A bare object const widens required: true to boolean; generic inference through this call preserves the literal, which the defaults check below depends on. One call, zero runtime cost.
  • ExtractPropDefaultTypes filters required props. Props declared required: true can never carry a default, so they no longer appear in the defaults map's type. The Omit<...> wrappers that stripped them by hand die; a deliberately default-free optional prop is declared key: undefined — the ruling stated in the defaults object itself. Together with propsWithDefaults this completes the extensible contract system: types, defaults, and the merged props object are plain namespace data a subclass composes by spread. The Extensible Components guide is the full reference.

Fixed ​

  • Static() re-wrapping a subclass could resurrect a parent-bound method. The wrap walk treated an already-wrapped ancestor's bind/cache symbol properties as API and re-installed them on the child, where the child's own chain lookup expected to bind for itself. The walk now recognizes every bind/cache symbol the module ever issues — registered and unregistered alike — and skips its own runtime residue. Double-wrapped subclass chains bind correctly.

The standard (ships in the tarball — npx ivue skill) ​

The operating manual grew four rulings since 2.4.0, each mirrored at ivue.dev/guide/standard:

  • One seam per module. A class file holds exactly three residents: imports, the class, the namespace — in Identity → Values → Types order. File-private values are non-exported namespace members.

  • Two-tier props contracts. Small surfaces author the contract inline in the namespace; large ones author it in a sibling XProps.ts that the namespace re-exports 1:1. Consumers read the namespace either way.

  • Overrides say so out loud. noImplicitOverride is on and every overriding member carries override — a base rename breaks every subclass at the exact member instead of silently orphaning it.

  • private is banned. Visibility is a three-tier statement of audience: public for consumers, protected for subclasses, private for nobody. The reasoning is the Ban private post.

  • A runnable gate. skills/ivue/ivue-standards-check.ts checks a tree against the standard from the command line (npm run gate wires it in this repo), with a JSON skip list for rulings, a bootstrapCli seam that makes a house-specific subclass gate three getters and one line, and an opt-in GeneratorStandard extension carrying the invariant-methodology checks.

Measured ​

Engine: 1,146 B gzipped (gzip -c dist/index.es.js | wc -c). Tests: 209 passing, 100% coverage on every metric (statements, branches, functions, lines) across Reactive.ts, Static.ts, ivue.ts, kernel.ts, extras.ts, LazyShared.ts, index.ts.

Released under the MIT License.