🤸‍♀️

wonder-slim

ERExtensions, Ajax and JavaWOExtensions. The basics.

Version
v8.0.4
Updated
Sep 4

8.0.4

v8.0.4 Sep 4 on GitHub ↗

The theme of this release: the page cache became one honest, observable, self-defending thing — and AjaxSlim finished its pre-adoption hardening.

Page cache: measured and self-defending

  • Reuse statistics — every restore records the instance's idle time and LRU depth into app-wide histograms on the session cache overview page, with a reverse-cumulative "broken by bound" column that reads directly as "a TTL or cap at this bound would have broken N restores". Restores broken by session expiry — invisible to in-cache counters — are counted too, at the restoreSessionWithID choke point. A notable-reaches list names the pages users actually come back for.
  • ERXPageCachePressureValve — caches trim themselves under real memory pressure instead of paying an always-on TTL: when a GC completes with old gen still above 85%, sessions are trimmed to 50% of the page cache cap (LRU-first); above 90%, to 25%. Never below a session's current page. Push-based (collection-usage notifications — no polling, no forced GCs), throttled, loudly logged, surfaced on the overview page and the startup banner. Thresholds and fractions are properties; er.extensions.ERXPageCachePressureValve.enabled=false opts out. It also finally subscribes to ERXLowMemoryHandler's long-unsubscribed low-memory notifications.

AjaxSlim

  • AjaxExpansion — the disclosure-section element rebuilt on native <details>/<summary>: four bindings, instant client-side toggling, and open state that survives morphs of enclosing containers (each toggle pings the server, so every re-render carries the correct open attribute). Legacy effect bindings and lazy content loading are gone.
  • AjaxModalContainer closes on backdrop click — clicks inside the dialog's box, and drags that merely end outside, never dismiss.
  • Pre-adoption hardening: an open modal survives morphs of enclosing regions; a full-document ajax response (the expired-session shape) is diverted to the error contract instead of being swallowed or morphed into a container; AjaxSelfUpdatingContainer.action no longer fires when the container is merely another trigger's render target; field observers no longer fire into a real form submission; focus survives tabbing out of a field that triggers a morph, including multi-container updates.
  • Full .apiext adoption — typed cross-binding constraints, defaults, deprecations, unknown-attribute and content policies on every element.

Development mode

  • /eval — a JShell REPL inside the running app (loopback-only), and /problems — the rendered binding-error boxes as JSON; both aligned with ng-objects' dev endpoints. Dev-loop machinery consolidated under er.extensions.dev; apps report runtime and pid to the dev server; the launch banner prints external direct-connect URLs.

Dependencies

  • Releases now depend only on published artifacts: parsley pinned to 1.6.0, and the ng-core compile dependency severed by temporarily vendoring four small dev-mode classes into er.extensions.dev.ng (each file documents its deletion condition). Also: json 20260719, junit 6.1.3, vermilingua 1.1.7.

Smaller things

  • The empty-update 500 explains itself instead of shrugging; experimental SVG-aware ERXWOImage (opt-in); ERXWOTextField cleanups; RouteTable names its unhandled-response userInfo key.

8.0.3

v8.0.3 Jun 26 on GitHub ↗

ERExtensions

  • Element substitutions are now declarative. The Wonder element replacements (WOStringERXWOString, WOFormERXWOForm, and the rest) are no longer installed by runtime class-swapping at startup — they're declared in a parsley-tag-aliases.properties resource that Parsley resolves at parse time. This removes runtime class introspection at boot and makes the substitutions visible to tooling. Requires Parsley 1.6.0.
  • Richer Ajax page-cache diagnostics in the exception/error pages, to make page-cache issues (e.g. "backtracked too far") easier to debug.
  • Internal cleanup of freestyle-URL handling in ERXApplication.

AjaxSlim

AjaxSlim continued to evolve substantially this cycle — morph-native updates, server-side update targeting, a cleaner element/protocol API split, drag-and-drop visual cues, and the new .apiext element-API format driving its reference. It's moving fast; see the commit history for specifics.

Dependencies

  • Parsley 1.6.0 (required by the declarative element substitutions).

Full changelog: https://github.com/undur/wonder-slim/compare/v8.0.2...v8.0.3

8.0.2

v8.0.2 Jun 18 on GitHub ↗

The headline of this release is AjaxSlim — a new, modern, morph-native Ajax framework — alongside fixes and dev-experience polish in the existing frameworks.

Existing applications using the legacy Ajax framework in the default configuration can upgrade safely: a full audit of every changed shared-framework file confirmed no observable change in production beyond the two deliberate behavior changes noted below.

⚠️ Behavior changes to be aware of

  • Ajax page-restoration errors now return HTTP 500 (was HTTP 200). When a page has aged out of the cache ("backtracked too far"), the error response now carries a 500 status instead of 200. Prototype-based Ajax flows (AjaxUpdateContainer / AjaxObserveField / AjaxUpdateLink) consequently invoke their onFailure path instead of onSuccess — so a stale-link Ajax request now surfaces a failure to the user instead of silently morphing the error page into the DOM. This is an intentional correctness fix.
  • Development mode now injects a Parsley "controls strip" (plus console capture) into every HTML page.

AjaxSlim (new framework)

  • A morph-native, fetch-based, dependency-free rebuild of the core Ajax update spine — no Prototype, no Scriptaculous. Elements live in package er.ajax as a drop-in replacement for the legacy Ajax framework (the two cannot share a classpath; AjaxSlim replaces Ajax).
  • DOM updates reconcile via Idiomorph by default, preserving focus / scroll / selection / unchanged subtrees.
  • Core elements: AjaxUpdateContainer, AjaxSelfUpdatingContainer, AjaxUpdateLink, AjaxObserveField, AjaxSubmitButton, AjaxUpdateTrigger, plus AjaxModalContainer (native <dialog>), AjaxBusySpinner, AjaxPing, and AjaxSortable (drag-to-reorder).
  • Multi-container update in a single round-trip.
  • Errors during an Ajax request are now shown to the user in an overlay that renders the server's actual response (e.g. the exception page), instead of being silently swallowed or morphed into the page.
  • AjaxPlayground — a login-free, database-free demo app bundled in the repo that exercises every AjaxSlim element together, with component-gallery pages, an element reference, and "danger-matrix" scenario pages. Clone the repo and run it to try the new framework hands-on.

New elements: AjaxPopUpButton & AjaxBrowser

  • AjaxPopUpButton — a searchable, morph-native single-select (a WOPopUpButton drop-in) built on the wonder-select widget, with type-to-search, keyboard navigation, and viewport-aware dropdown sizing.
  • AjaxBrowser — the multi-select counterpart, for picking several values from a searchable list.

Legacy Ajax framework

  • AjaxUpdateContainer gains an opt-in morph="$true" binding (Idiomorph reconciliation). The default remains classic innerHTML replacement, so existing apps are unchanged.
  • Removed dead/unused subsystems: AjaxFlexibleFileUpload, AjaxSocialNetwork(Link), AjaxProxy, and the entire jabsorb / JSON-RPC stack (er.ajax.json.*).

ERExtensions / ajax session

  • Ajax page cache reworked: keyed by (page, container) with the container fallback scoped to the request's own page instance (fixes cross-instance content bleed); fragment-cache eviction is now least-recently-used.
  • Failed ajax page-cache lookups log a WARN instead of failing silently.
  • Page cache configuration is logged at launch.

Dependencies

  • Parsley pinned to released 1.5.0.

Full changelog: https://github.com/undur/wonder-slim/compare/v8.0.1...v8.0.2

8.0.1

v8.0.1 Jun 1 on GitHub ↗

Maintenance + dev-experience polish release.

Dev experience

  • Direct connect URL now prints http://localhost:<port> in dev mode — sidesteps mDNS / firewall friction when connecting from the same machine.
  • Direct connect URL is on its own line at startup so it's double-clickable in most terminals.
  • Nicer initial logging at application startup.

Exception page

  • Component source / context info is now shown on the exception page.
  • Java context and WO hierarchy are visually separated.
  • Parse location is preserved from the originally thrown exception (better template error reporting).

Robustness

  • Accept-Language header parsing now tolerates malformed q= values instead of throwing.

Cleanup

  • RouteRequestHandler removed — folded into existing handler machinery.
  • Multiple NSLog call sites replaced with slf4j (ERXApplication, ERXLowMemoryHandler, WXOutlineEntry).

Dependencies

  • parsley 1.4.1 → 1.4.2
  • slf4j 2.0.17 → 2.0.18
  • junit 6.0.3 → 6.1.0

Maven

<dependency>
    <groupId>is.rebbi.slim</groupId>
    <artifactId>ERExtensions</artifactId>
    <version>8.0.1</version>
</dependency>

Full changelog: https://github.com/undur/wonder-slim/compare/v8.0.0...v8.0.1

8.0.0

v8.0.0 Apr 30 on GitHub ↗

First official release to maven.wocommunity.org

Changes

  • Everything

Full Changelog since forking from the original Project Wonder: https://github.com/undur/wonder-slim/compare/project-wonder...v8.0.0