@energy8platform/shell 0.7.1 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/html.cjs.js CHANGED
@@ -1693,7 +1693,7 @@ class KeyboardController {
1693
1693
 
1694
1694
  // AUTO-GENERATED by scripts/gen-version.mjs — do not edit. Mirrors package.json "version".
1695
1695
  /** The @energy8platform/shell package version, stamped into the game-info footer. */
1696
- const PACKAGE_VERSION = '0.7.1';
1696
+ const PACKAGE_VERSION = '0.7.2';
1697
1697
 
1698
1698
  /** Apply defaults to the raw config (the mount target lives on the renderer, not here). */
1699
1699
  function resolveConfig(config) {
package/dist/html.d.ts CHANGED
@@ -631,7 +631,7 @@ declare class ShellController extends EventEmitter<ShellEvents> implements Shell
631
631
  tokens: ShellTokens;
632
632
  layout: ShellLayoutMode;
633
633
  soundOn: boolean;
634
- readonly engineVersion = "0.7.1";
634
+ readonly engineVersion = "0.7.2";
635
635
  readonly actions: ShellActions;
636
636
  private renderer;
637
637
  private i18n;
@@ -776,7 +776,7 @@ interface I18n {
776
776
  declare function createI18n(opts: I18nOptions): I18n;
777
777
 
778
778
  /** The @energy8platform/shell package version, stamped into the game-info footer. */
779
- declare const PACKAGE_VERSION = "0.7.1";
779
+ declare const PACKAGE_VERSION = "0.7.2";
780
780
 
781
781
  /** A shell: the renderer-agnostic controller plus the surface facade (safeArea/barHeight/setVisible)
782
782
  * an embedding host reads. `createShell`, `createGameShell` and `createPixiShell` all return this. */
package/dist/html.esm.js CHANGED
@@ -1691,7 +1691,7 @@ class KeyboardController {
1691
1691
 
1692
1692
  // AUTO-GENERATED by scripts/gen-version.mjs — do not edit. Mirrors package.json "version".
1693
1693
  /** The @energy8platform/shell package version, stamped into the game-info footer. */
1694
- const PACKAGE_VERSION = '0.7.1';
1694
+ const PACKAGE_VERSION = '0.7.2';
1695
1695
 
1696
1696
  /** Apply defaults to the raw config (the mount target lives on the renderer, not here). */
1697
1697
  function resolveConfig(config) {
package/dist/index.cjs.js CHANGED
@@ -1667,7 +1667,7 @@ class KeyboardController {
1667
1667
 
1668
1668
  // AUTO-GENERATED by scripts/gen-version.mjs — do not edit. Mirrors package.json "version".
1669
1669
  /** The @energy8platform/shell package version, stamped into the game-info footer. */
1670
- const PACKAGE_VERSION = '0.7.1';
1670
+ const PACKAGE_VERSION = '0.7.2';
1671
1671
 
1672
1672
  /** Apply defaults to the raw config (the mount target lives on the renderer, not here). */
1673
1673
  function resolveConfig(config) {
package/dist/index.d.ts CHANGED
@@ -631,7 +631,7 @@ declare class ShellController extends EventEmitter<ShellEvents> implements Shell
631
631
  tokens: ShellTokens;
632
632
  layout: ShellLayoutMode;
633
633
  soundOn: boolean;
634
- readonly engineVersion = "0.7.1";
634
+ readonly engineVersion = "0.7.2";
635
635
  readonly actions: ShellActions;
636
636
  private renderer;
637
637
  private i18n;
@@ -776,7 +776,7 @@ interface I18n {
776
776
  declare function createI18n(opts: I18nOptions): I18n;
777
777
 
778
778
  /** The @energy8platform/shell package version, stamped into the game-info footer. */
779
- declare const PACKAGE_VERSION = "0.7.1";
779
+ declare const PACKAGE_VERSION = "0.7.2";
780
780
 
781
781
  /** A shell: the renderer-agnostic controller plus the surface facade (safeArea/barHeight/setVisible)
782
782
  * an embedding host reads. `createShell`, `createGameShell` and `createPixiShell` all return this. */
package/dist/index.esm.js CHANGED
@@ -1665,7 +1665,7 @@ class KeyboardController {
1665
1665
 
1666
1666
  // AUTO-GENERATED by scripts/gen-version.mjs — do not edit. Mirrors package.json "version".
1667
1667
  /** The @energy8platform/shell package version, stamped into the game-info footer. */
1668
- const PACKAGE_VERSION = '0.7.1';
1668
+ const PACKAGE_VERSION = '0.7.2';
1669
1669
 
1670
1670
  /** Apply defaults to the raw config (the mount target lives on the renderer, not here). */
1671
1671
  function resolveConfig(config) {
package/dist/pixi.cjs.js CHANGED
@@ -1694,7 +1694,7 @@ class KeyboardController {
1694
1694
 
1695
1695
  // AUTO-GENERATED by scripts/gen-version.mjs — do not edit. Mirrors package.json "version".
1696
1696
  /** The @energy8platform/shell package version, stamped into the game-info footer. */
1697
- const PACKAGE_VERSION = '0.7.1';
1697
+ const PACKAGE_VERSION = '0.7.2';
1698
1698
 
1699
1699
  /** Apply defaults to the raw config (the mount target lives on the renderer, not here). */
1700
1700
  function resolveConfig(config) {
@@ -2326,7 +2326,22 @@ function prefersReducedMotion() {
2326
2326
  }
2327
2327
  const easeOutCubic = (p) => 1 - Math.pow(1 - p, 3);
2328
2328
 
2329
- /** Tween 0→1 on the Pixi ticker. Returns a canceler. Skips to the end when motion is reduced. */
2329
+ /**
2330
+ * Tween 0→1 on the Pixi ticker. Returns a canceler. Skips to the end when motion is reduced.
2331
+ *
2332
+ * CONTRACT — when motion is reduced (or `duration <= 0`) this tween does NOT animate: it applies
2333
+ * the final value and calls `onComplete` SYNCHRONOUSLY, before returning. Callers depend on that
2334
+ * (`PixiRenderer.destroy` resolves its teardown promise from `onComplete`, and must not wait on a
2335
+ * ticker that may already be stopped), so it must stay synchronous.
2336
+ *
2337
+ * The consequence for callers: `onComplete` is NOT an async boundary. An `onComplete` that starts
2338
+ * another tween is then direct recursion with no unwind — tween → onComplete → tween → … until
2339
+ * `RangeError: Maximum call stack size exceeded`. That shipped once: the CTA pulse loop
2340
+ * (`widgets.ts` startPulse) restarted itself from `onComplete`, so every player running the OS
2341
+ * "reduce motion" setting crashed the instant the buy-bonus panel painted its hovered CTA. Any
2342
+ * looping animation must therefore check `prefersReducedMotion()` and not loop — which is also
2343
+ * what reduced motion is asking for.
2344
+ */
2330
2345
  function tween(ticker, opts) {
2331
2346
  const ease = opts.ease ?? easeOutCubic;
2332
2347
  if (prefersReducedMotion() || opts.duration <= 0) {
@@ -3298,6 +3313,15 @@ class BuyBonusBadge extends pixi_js.Container {
3298
3313
  startPulse() {
3299
3314
  if (this.pulseCancel)
3300
3315
  return;
3316
+ // A pulse is exactly the kind of looping decoration "reduce motion" asks us to drop — and
3317
+ // under it `tween` has nothing to animate anyway: it snaps to the end and calls `onComplete`
3318
+ // SYNCHRONOUSLY (see its contract), which this loop would answer by starting another one, and
3319
+ // another, with no unwind — `RangeError: Maximum call stack size exceeded`. That was a live
3320
+ // Stake crash: with the OS "reduce motion" setting on, opening the buy-bonus panel painted its
3321
+ // hovered CTA and killed the game, so the player could never buy. Now the button simply sits
3322
+ // still at scale 1.
3323
+ if (prefersReducedMotion())
3324
+ return;
3301
3325
  // both the label (anchor 0.5) and the icon (pivot centred) scale around their centre
3302
3326
  const loop = () => {
3303
3327
  this.pulseCancel = tween(this.ticker, {