Releases: ParthJadhav/RageLayer
Release list
v2.1.3
Patch Changes
- #29
41bb2ffThanks @ParthJadhav! - Polish the built-in destruction experience: keep fire alight longer, make acid pour and persist from a procedural jar, add red-hot laser-cut lips, fix the water-hose toolbar icon crop, and remove Gravity Gun from the default tool lineup.
v2.1.2
Patch Changes
-
#25
5de7d62Thanks @ParthJadhav! - fix: cancelled gestures discard queued pointer moves; pointer input extracted from the engineAdministrative gesture cancellation (undo, redo, clear) now drops any pointer
moves still queued for the frame — previously the next frame could replay
pre-undo movement through the active tool and land fresh damage on the pixels
the undo had just restored. Pointer handlers also stop reacting once the
engine is disposed, not just while paused.Internally, the full pointer gesture lifecycle (event binding, pointer
capture, bounded move coalescing, cancellation, scripted strikes) moved out of
RageLayerEngineintosrc/pointer-input.tsbehind a narrow host interface,
with direct unit tests; the write-only perf-counter types moved to
src/perf-counters.ts, and narrow-phase collision was decoupled from the
physicsBodyvia a minimalCollisionBodycontract. No public API changes.
v2.1.1
Patch Changes
-
#23
186ed09Thanks @ParthJadhav! - perf: cache the void mask as an inverse-alpha band and erase with destination-out on slow-canvas browsersThe frame's "void mask" — which clips surface-bound effects (bugs, water,
flames) to the page's surviving pixels — used to be one full-band
destination-indraw of the content surface. On CPU-rasterized Canvas2D
(Firefox/Gecko, and WebKit's non-GL path) that op is doubly poisonous: it
touches every pixel of the fx canvas, and it knocks the canvas off the
accelerated path so every later canvas-source draw in the same frame (smoke,
steam, flame sprites) pays a fixed toll. Heavy water and bug scenarios ran
3–5× slower than Chrome at desktop viewports.Browsers whose canvas→GL upload probe reads slow now mask with one
destination-outdraw of a cached inverse of the visible band's page alpha
(opaque where the page is gone, including past the document's edges) —
fx · (1 − holes) is exactly fx · pageAlpha, anddestination-outleaves
pixels outside its source untouched, so nothing deopts. The cache rebuilds on
scroll or resize and otherwise refreshes only the accumulated surface-damage
rect. Independently, the opacity map now tracks which 128px cells might be
missing alpha, so frames with no holes in view skip the mask outright in
every browser; fast-canvas browsers (Chrome) keep the original single
destination-indraw. Interleaved A/B on Firefox at 1904×1034: flood and
swarm gain ~17ms/frame, mayhem ~2ms, inferno and singularity unchanged;
Chrome is unchanged.
v2.1.0
Minor Changes
- #21
8eb21a7Thanks @ParthJadhav! - Probe canvas→texture upload cost at runtime and keep the WebGL surface shading and post-FX bloom on their plain-2D fallbacks where uploads are slow. Chromium uploads canvas sources GPU-to-GPU (~0.01 ms) and keeps the full pipeline; Firefox and WebKit currently pay a fixed multi-millisecond toll per upload call, which made heavy scenes run at single-digit FPS (measured 4.5 → 45 FPS on the worst-case stress scenario in Firefox, 13 → 60 FPS in WebKit). Destruction visuals are unchanged on those browsers — only glass-edge shading, page warp, bloom, and heat shimmer switch off. The probed cost is reported assample.gpu.uploadCostMsin performance snapshots, and a Playwright-based cross-browser stress runner (bun run perf:browsers) drives the same scenarios in Firefox, WebKit, and Chrome.
v2.0.0
Major Changes
-
#19
eb78b20Thanks @ParthJadhav! - Remove keyboard aiming and the whole-page collapseTwo toolbar actions are gone, along with everything behind them.
The collapse action. The
Xshortcut, the toolbar button,engine.collapse(), the
element-by-element fall queue, and thecollapseMsfield ofPerformanceFrameBreakdown.
harvestElementsstill measures the page —engine.demolish(x, y)continues to knock individual
elements loose, andelementsInBand()is still exported if you want to drive a wave yourself.Keyboard aiming. The
Ashortcut, the crosshair button, the arrow/Enter/Eschandling, the
on-canvas reticle,engine.setAim(),engine.aim,ToolbarModel.startAiming()/stopAiming()/
moveAim()/strikeAtAim(), theaimStepandstrikeHoldMsmodel options,ToolbarState.aim,
ToolbarState.announcementand its live region, and thekeyboardCursor,keyboardCursorHint,
keyboardMovedandkeyboardStruckstrings.Accessibility impact — please read
Aiming mode was how a visitor without a pointing device actually used a tool. The toolbar remains
fully keyboard-operable, but the canvas is a pointer surface and now has no built-in keyboard route:
a keyboard-only visitor can select the hammer and not swing it.engine.strike(x, y, { holdMs })is unchanged and still public. It runs the sameonDown/onUp
pair a click produces and takes a history checkpoint, so a host that needs keyboard operation can
rebuild it — supplying the cursor, the key handling, and the live region itself. Treat RageLayer as
strictly optional decoration and keep real content and controls out from behind it.Migration
engine.collapse()— no replacement. Callengine.demolish(x, y)per element, or
engine.fracture(x, y, r, { power })across the viewport.engine.setAim()/engine.aim— track the cursor in your own state and draw it yourself.model.strikeAtAim()— callengine.strike(x, y, { holdMs: 260 })with your own coordinates.state.aim/state.announcement— removed fromToolbarState; own them in the host.- Custom
stringsobjects: the fourkeyboard*keys andcollapseare no longer read.
Partial<RageLayerStrings>will now reject them as unknown properties. TOOLBAR_ICONSno longer hasaimorcollapseentries, andToolbarIconNameno longer
includes those names.PerformanceFrameBreakdown.collapseMs— removed; the time it measured no longer exists.
formatStringis still exported, though no built-in string carries a placeholder now.
v1.0.0
Major Changes
-
a084549Thanks @ParthJadhav! - Remove tool loadouts and show the complete toolset everywhere. Theragelayer/loadoutsentry point,
BUILT_IN_LOADOUTS,createToolLoadout(),resolveToolLoadout(), theloadoutoption on
mountRageLayer()/createRageLayer(), theloadoutprop on the React and Vue components, and the
loadoutattribute on<rage-layer>are all gone. Every toolbar now registers and shows all sixteen
built-in tools; pass atoolsarray to narrow the set.mountRageLayer()selects"hammer"when
initialToolis omitted, as it already did without a loadout.Redesign the toolbar. Action buttons are single-path SVG icons drawn in
currentColorinstead of
emoji, so their idle, hover and disabled states are driven by one colour token — disabled controls
dim their ink rather than washing out the whole button, which had left undo and redo nearly
invisible. The bar, hint pill and status chip share one set of surface tokens, the selected tool
carries a tinted fill plus a dock-style accent marker, and buttons are 40px on desktop and a full
44px once the row scrolls on narrow screens.ToolbarButton.glyphandToolbarButton.fontSizeare
replaced byToolbarButton.iconPath; the newTOOLBAR_ICONS,toolbarIconSvg()and
toolbarIconElement()exports let a host-built toolbar render the same icons. -
#10
cecc8f2Thanks @ParthJadhav! - Rename the lastDestroyer*public names to match the package.DestroyerEngineis now
RageLayerEngine,DestroyerEngineApiisRageLayerEngineApi,DestroyerOptionsis
RageLayerEngineOptions,DestroyerStringsisRageLayerStrings,DestroyerToolStringsis
RageLayerToolStrings, and the<rage-layer>element propertydestroyerEngineis
rageLayerEngine. There are no deprecated aliases — the old names are gone, and
bun run check:packageasserts they stay gone.Migration is a rename in place; no behaviour, option, or DOM contract changed. Entry points
(ragelayer/react, …), attributes (data-ragelayer-*) and events (ragelayer-close,
ragelayerchange) were already correct and are untouched.The demo toolbar also showed a stale
Destroyerbrand label; it now readsRageLayer, matching
every other piece of display text. -
a084549Thanks @ParthJadhav! - Replace configurable page materials with one fixed wood-like physical response. This removes the
material registry, material definitions and DOM material attributes from the public API. It also
removes Freeze Ray, Wrecking Ball, and Glitch Gun, reducing the built-in set to 16 tools: seven base,
five heavy, and four advanced.Laser Cutter now cuts structure immediately like the Chainsaw and drops isolated pieces. Acid
Sprayer keeps visible and structural impacts aligned and spreads a short, bounded distance around
each deposit, with a persistent reaction rim that stays clipped to surviving wood. Fire spreads
across surviving content with a coherent baked flame body and a bounded smoke plume. Paintball
supports automatic fire while held, and the Water Hose uses a compact pressure-nozzle model. The
Gun model now has a more complete silhouette, working slide, and firing-cadence recoil.Toolbars also keep usage hints visible, share keyboard aiming and translations across React, Vue,
and the custom element, and provide non-shrinking 44px touch targets on narrow screens.
Built-in cooldowns, gesture paths and delayed effects are now isolated per engine, so simultaneous
mounted layers cannot advance or clear one another's tool state. Timed effects continue after tool
switches, while settled built-ins stop requesting idle animation frames even when their 3D model
remains visible under a stationary pointer. Waking an idle loop no longer integrates its sleeping
interval, and faded tool-audio loops are stopped and disconnected instead of processing silently.
Patch Changes
-
a084549Thanks @ParthJadhav! - Live capture mode now shows DOM mutations. The mirror's repaint fast path redraws a mounted clone, so a counter ticking in page DOM — or anything inserted after the capture — never appeared on screen. AMutationObserveron the capture root (mutations insidecaptureFilter-excluded elements don't count) now marks the mirror stale so the next refresh re-clones, and the refresh loop presents the recomposed band itself so an idle page — whose frame loop is parked — actually shows it. -
278287cThanks @ParthJadhav! - Display text now readsRageLayerconsistently. Console warnings use the[RageLayer]prefix instead of[ragelayer], and shared screenshots download asRageLayer-<timestamp>.png. The package name, entry points (ragelayer/react, …), DOM attributes (data-ragelayer-*), and events (ragelayer-close,ragelayerchange) are unchanged — npm forbids uppercase in package names, and the DOM contracts stay case-stable.
v0.6.1
Patch Changes
67a435eThanks @ParthJadhav! - Harden npm releases with token-free trusted publishing and retry registry artifact downloads while a new version propagates.
v0.6.0
Minor Changes
dcad2c8Thanks @ParthJadhav! - Rename the package and project to RageLayer. Public framework components and lifecycle helpers now use theRageLayername, the Svelte action isrageLayer, and the custom element is<rage-layer>. Package-prefixed DOM attributes, events, constants, CSS hooks, and development environment variables now use theragelayer,RAGELAYER, orrl-prefix.
v0.5.0
Minor Changes
b3b99eaThanks @ParthJadhav! - Rename the package and project to RageKit. The React and Vue components are nowRageKit, lifecycle helpers arecreateRageKit,mountRageKit, anduseRageKit, the Svelte action isrageKit, and the custom element is<rage-kit>. Package-prefixed DOM attributes, events, constants, and development environment variables now use theragekitorRAGEKITprefix.
v0.4.0
Minor Changes
-
1289409Thanks @ParthJadhav! - Add a framework-neutral lifecycle controller, a headless React hook, a Vue composable, and a
Svelte action. Publish explicitreact,vue, andsvelteentry points, preserve React's client
boundary for Next.js, reduce the package contents, and add a documentation site and reliable npm
release workflow. The engine now defaults sound off and followsprefers-reduced-motionfor camera
shake and nonessential UI transitions.Add size-focused
engine,tools,tools/heavy, andlazyentry points; configurable procedural
model scaling; exact built-in icon silhouettes that avoid canvas readbacks; explicit pause/resume;
automatic hidden-tab suspension; data-saver quality detection; dynamic-layout observation; and
robust primary-pointer capture/cancellation for touch and pen input.Add six advanced tools—Gravity Gun, Laser Cutter, Acid Sprayer, Wrecking Ball, Sticky Bombs, and
Glitch Gun—with split loading and measured procedural-model bounds. Add material-aware fire,
fracture, laser, acid, and electrical behavior; seven bounded spatial tool combos; opt-in,
pixel-budgeted destruction undo/redo; immutable built-in and custom tool loadouts; and a typed
state-isolated custom-tool SDK. Publishtools/advanced,loadouts, andsdkentry points and
cover them in consumer fixtures, the live demo, package validation, and documentation.Cap the transient effects layer at CSS-pixel resolution by default to avoid DPR-squared
Canvas2D-to-WebGL upload cost, with aneffectsPixelRatiooverride for explicit supersampling.
The balanced adaptive-quality tier now disables the measured post-processing bottleneck immediately
instead of retaining it until a second downgrade. -
1289409Thanks @ParthJadhav! - Add a ready-made toolbar for every stack, keyboard-operable tools, translatable strings, and a
channel for reporting degradation.desktop-destroyer/elementregisters<desktop-destroyer>, a complete toolbar in a shadow root
that works unchanged in Svelte, Angular, Solid, Qwik, Astro and plain HTML./vuenow exports a
DesktopDestroyercomponent alongside the composable. Both, and the React component, render one
sharedToolbarModel, published asdesktop-destroyer/toolbarfor hosts building their own UI.- Keyboard aiming makes the tools reachable without a pointer:
Aplaces a cursor on the page,
arrows steer it,Enteruses the tool, and moves and strikes are announced. The underlying
engine.strike(x, y, { holdMs })andengine.setAim()are public, and a keyboard blow is
undoable like any other. Custom tools need no changes to be reachable this way. - Every user-visible string, including tool names and hints, can be replaced through
strings, so
the toy can be translated or reworded.DEFAULT_STRINGSandresolveStrings()are exported. onError(option,engine.onError(),engine.errorand an"error"event) reports the
failures that were previously only aconsole.warn: capture failure, live-capture fallback,
element-harvest failure, a missing text mask, and page-height truncation. Registering a handler
silences the matching warning so nothing is logged twice.engine.historyEnableddistinguishes "undo is on" from "there is something to undo", so a
toolbar can show its undo controls from the start instead of having them appear mid-session.
Patch Changes
-
1289409Thanks @ParthJadhav! - Bundle thehtml-to-imagecapture code into the package as a lazily-loaded chunk and drop the
runtime dependency. Loadingdistdirectly in a browser (the demo, harnesses, benchmarks, CDN
usage) previously failed to resolve the bare specifier and silently degraded to overlay mode —
no destructible page content, no fracture debris, and content-dependent tools (laser cutter, acid
sprayer, bugs, demolition chunks) did nothing.Fix the broom leaving a trail of phantom torn-edge rings on intact pages:
ContentLayer.restore
now composes its pristine disc on a scratch canvas and stamps it in one draw, instead of a
clip + clear + draw sequence that antialiased the rim twice and left a partial-alpha seam the
surface shader shaded as a wound.Make the Glitch Gun read on light backgrounds: corruption now tears real page slices sideways and
composites its interference bars withdifferenceinstead ofscreen, which was nearly invisible
against white.The demo toolbar now exercises the full public surface: built-in loadout switching, undo/redo,
whole-page repair, snapshot download, sound and pause toggles, combo toasts, and a live
fps/capture status readout. -
1289409Thanks @ParthJadhav! - Test the destruction pipeline for real, and harden the release path.Unit tests now run against a DOM with a real Canvas2D rasterizer, so the coverage map, wound
compositing, physics solver and every built-in tool are asserted on actual pixels rather than
mocks — 274 tests, up from 57, taking line coverage from 44% to 85%. A new runtime suite
(bun run test:browser) drives the built package through headless Chrome and asserts what a
visitor sees: the page is captured, the WebGL2 surface shader comes up, tools punch real holes,
undo restores them, and disposing puts the real page back. Both run in CI, with coverage floors
and a per-module gate.Also fixes
import "desktop-destroyer/element"throwing when evaluated on a server, and stops
bundlers from tree-shaking away the element's registration.