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 widensrequired: truetoboolean; generic inference through this call preserves the literal, which the defaults check below depends on. One call, zero runtime cost.ExtractPropDefaultTypesfilters required props. Props declaredrequired: truecan never carry a default, so they no longer appear in the defaults map's type. TheOmit<...>wrappers that stripped them by hand die; a deliberately default-free optional prop is declaredkey: undefined— the ruling stated in the defaults object itself. Together withpropsWithDefaultsthis 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.tsthat the namespace re-exports 1:1. Consumers read the namespace either way.Overrides say so out loud.
noImplicitOverrideis on and every overriding member carriesoverride— a base rename breaks every subclass at the exact member instead of silently orphaning it.privateis banned. Visibility is a three-tier statement of audience:publicfor consumers,protectedfor subclasses,privatefor nobody. The reasoning is the Ban private post.A runnable gate.
skills/ivue/ivue-standards-check.tschecks a tree against the standard from the command line (npm run gatewires it in this repo), with a JSON skip list for rulings, abootstrapCliseam that makes a house-specific subclass gate three getters and one line, and an opt-inGeneratorStandardextension 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.