@energy8platform/shell 0.6.3 → 0.6.5

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.d.ts CHANGED
@@ -450,6 +450,11 @@ interface ShellHost {
450
450
  setVolumeRefresh(fn: ((key: VolumeKey, value: number) => void) | null): void;
451
451
  /** Logic-bearing actions invoked by renderer controls. */
452
452
  readonly actions: ShellActions;
453
+ /** Re-show the replay summary modal through the controller (keeps its OverlayHandle in sync).
454
+ * Used as the modal's own reopen callback after START REPLAY, so a renderer never re-pushes a
455
+ * replay modal behind the controller's back (which would strand `overlay` and dead-end the
456
+ * next close). */
457
+ openReplay(opts: ReplayModalOptions): void;
453
458
  }
454
459
  /** Every state-changing thing a control can do. Each runs logic in the controller, emits the
455
460
  * matching event, and triggers a re-render. Renderers MUST route input through these. */
@@ -511,7 +516,7 @@ declare class ShellController extends EventEmitter<ShellEvents> implements Shell
511
516
  tokens: ShellTokens;
512
517
  layout: ShellLayoutMode;
513
518
  soundOn: boolean;
514
- readonly engineVersion = "0.6.3";
519
+ readonly engineVersion = "0.6.5";
515
520
  readonly actions: ShellActions;
516
521
  private renderer;
517
522
  private i18n;
@@ -593,7 +598,7 @@ interface I18n {
593
598
  declare function createI18n(opts: I18nOptions): I18n;
594
599
 
595
600
  /** The @energy8platform/shell package version, stamped into the game-info footer. */
596
- declare const PACKAGE_VERSION = "0.6.3";
601
+ declare const PACKAGE_VERSION = "0.6.5";
597
602
 
598
603
  /** A shell: the renderer-agnostic controller plus the surface facade (safeArea/barHeight/setVisible)
599
604
  * an embedding host reads. `createShell`, `createGameShell` and `createPixiShell` all return this. */
@@ -640,8 +645,6 @@ declare class HtmlRenderer implements ShellRenderer {
640
645
  fitBar(): void;
641
646
  private cancelMoneyAnims;
642
647
  private buildOverlay;
643
- /** Opens a replay modal and shows it — used as the reopen callback after START REPLAY. */
644
- private openReplayInternal;
645
648
  private showModal;
646
649
  /** Uniformly scale every open centred card modal (.ge-sheet) down so it fits a short/narrow
647
650
  * popout. Covers pickers, generic + replay modals, AND the buy-bonus confirm (which is hosted
package/dist/html.esm.js CHANGED
@@ -1218,12 +1218,19 @@ function normalizeLang(code) {
1218
1218
  return (LANG_SET.has(base) ? base : 'en');
1219
1219
  }
1220
1220
  function createI18n(opts) {
1221
- // Social is the `en-social` pseudo-locale: it rewrites the English source. Non-English locales are
1222
- // authored social-safe already, so `socialize` only runs on the English source string.
1221
+ // Social is the `en-social` pseudo-locale: it rewrites the English source into social-safe
1222
+ // vocabulary. The replacement dictionary only exists for English, so social mode FORCES English
1223
+ // the requested `language` is ignored, matching the `isSocial` contract ("…derived from English…
1224
+ // regardless of `language`"). Rendering a non-English locale in social mode would leak untranslated
1225
+ // restricted terms, so we never do it.
1226
+ if (opts.isSocial) {
1227
+ const t = (src) => socialize(src);
1228
+ return { lang: 'en', t };
1229
+ }
1223
1230
  const lang = normalizeLang(opts.language);
1224
1231
  const t = (src) => {
1225
1232
  if (lang === 'en')
1226
- return opts.isSocial ? socialize(src) : src;
1233
+ return src;
1227
1234
  return opts.messages?.[lang]?.[src] ?? LOCALES[lang]?.[src] ?? src;
1228
1235
  };
1229
1236
  return { lang, t };
@@ -1446,7 +1453,7 @@ class KeyboardController {
1446
1453
 
1447
1454
  // AUTO-GENERATED by scripts/gen-version.mjs — do not edit. Mirrors package.json "version".
1448
1455
  /** The @energy8platform/shell package version, stamped into the game-info footer. */
1449
- const PACKAGE_VERSION = '0.6.3';
1456
+ const PACKAGE_VERSION = '0.6.5';
1450
1457
 
1451
1458
  /** Apply defaults to the raw config (the mount target lives on the renderer, not here). */
1452
1459
  function resolveConfig(config) {
@@ -4018,7 +4025,9 @@ class HtmlRenderer {
4018
4025
  }
4019
4026
  case 'replay': {
4020
4027
  const opts = req.opts;
4021
- const reopen = () => { this.openReplayInternal(opts); };
4028
+ // Reopen through the controller (not a renderer-direct re-push) so its OverlayHandle stays
4029
+ // in sync — otherwise a reopened replay modal is untracked and the next close no-ops.
4030
+ const reopen = () => { this.host.openReplay(opts); };
4022
4031
  const root = buildReplayModal(this.host, opts, reopen);
4023
4032
  return { root };
4024
4033
  }
@@ -4028,14 +4037,6 @@ class HtmlRenderer {
4028
4037
  }
4029
4038
  }
4030
4039
  }
4031
- /** Opens a replay modal and shows it — used as the reopen callback after START REPLAY. */
4032
- openReplayInternal(opts) {
4033
- if (this.destroyed)
4034
- return;
4035
- const reopen = () => { this.openReplayInternal(opts); };
4036
- const root = buildReplayModal(this.host, opts, reopen);
4037
- this.showModal(root);
4038
- }
4039
4040
  showModal(el, onKey) {
4040
4041
  // Drop focus from any open shell control so a stray Space/Enter doesn't re-activate it
4041
4042
  const active = document.activeElement;