@moku-labs/game 0.15.42 → 0.15.44

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.
@@ -1,4 +1,4 @@
1
- import { m as StartedPage, r as GameConfig, t as AnyGameApp, u as PageOptions } from "../types-DQ9VHXun.mjs";
1
+ import { m as StartedPage, r as GameConfig, t as AnyGameApp, u as PageOptions } from "../types-CtpKlJTd.mjs";
2
2
 
3
3
  //#region src/app/page.d.ts
4
4
  /**
@@ -1,6 +1,6 @@
1
- import { Nr as PlayerStateProvider } from "../types-DrkR03nL.mjs";
2
- import { ht as PlatformProvider } from "../index-D12s9KZ2.mjs";
3
- import { _ as SystemShellFactory, g as SystemName, h as SystemModules } from "../types-DQ9VHXun.mjs";
1
+ import { Nr as PlayerStateProvider } from "../types-iOQUUB2R.mjs";
2
+ import { ht as PlatformProvider } from "../index-Cerx_CN_.mjs";
3
+ import { _ as SystemShellFactory, g as SystemName, h as SystemModules } from "../types-CtpKlJTd.mjs";
4
4
  import { Back, Haptics, KeepAwake, Lifecycle, Store } from "@moku-labs/system";
5
5
 
6
6
  //#region src/app/system.d.ts
package/dist/app.d.mts CHANGED
@@ -1,6 +1,6 @@
1
- import { Or as Json } from "./types-DrkR03nL.mjs";
2
- import { U as StringTable } from "./types-CFEtGENK.mjs";
3
- import { a as GameHandle, c as MemoryProvider, d as SaveKind, f as Scenario, g as SystemName, i as GameDefinition, l as PageAgent, n as GameApp, o as GamePluginConfigs, p as ScreenSeams, r as GameConfig, s as HeadlessSeams, v as WithGameState } from "./types-DQ9VHXun.mjs";
1
+ import { Or as Json } from "./types-iOQUUB2R.mjs";
2
+ import { U as StringTable } from "./types-GbVNkvJ4.mjs";
3
+ import { a as GameHandle, c as MemoryProvider, d as SaveKind, f as Scenario, g as SystemName, i as GameDefinition, l as PageAgent, n as GameApp, o as GamePluginConfigs, p as ScreenSeams, r as GameConfig, s as HeadlessSeams, v as WithGameState } from "./types-CtpKlJTd.mjs";
4
4
  import { AnyPluginInstance } from "@moku-labs/core";
5
5
 
6
6
  //#region src/app/define.d.ts
package/dist/app.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { Ft as audioPlugin, H as platformPlugin, i as screen, m as flattenFeatures, t as createApp, wt as effectsPlugin } from "./src-Bf1HeSRg.mjs";
1
+ import { Ft as audioPlugin, H as platformPlugin, i as screen, m as flattenFeatures, t as createApp, wt as effectsPlugin } from "./src-oM78C1_G.mjs";
2
2
  import { t as memory } from "./memory-CWlqhS7l.mjs";
3
3
  import { n as fakeClock, r as isFakeClock } from "./fake-hnJcJeYf.mjs";
4
4
  //#region src/app/define.ts
package/dist/assets.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { d as Manifest } from "./types-DrkR03nL.mjs";
1
+ import { d as Manifest } from "./types-iOQUUB2R.mjs";
2
2
 
3
3
  //#region src/plugins/assets/scan/cli.d.ts
4
4
  /**
@@ -1,8 +1,8 @@
1
- import { D as DebugSwitches, Hr as Api, Lr as Snapshot, Xr as FrameRate, Y as Api$1, ei as Time, nn as Api$2, or as FlowState, ot as Captured, rr as Bookmark, w as ScenesApi, zr as StoreApi } from "./types-DrkR03nL.mjs";
2
- import { P as AnimApi, a as AudioApi, h as EffectsApi, r as UiApi } from "./types-B-o8Ul1v.mjs";
3
- import { N as InputApi } from "./types-CFEtGENK.mjs";
4
- import { t as HeadlessApp } from "./headless-1e3gEF1Y.mjs";
5
- import { n as Command, r as ControlApp } from "./types-gQATSj41.mjs";
1
+ import { D as DebugSwitches, Hr as Api, Lr as Snapshot, Xr as FrameRate, Y as Api$1, ei as Time, nn as Api$2, or as FlowState, ot as Captured, rr as Bookmark, w as ScenesApi, zr as StoreApi } from "./types-iOQUUB2R.mjs";
2
+ import { P as AnimApi, a as AudioApi, h as EffectsApi, r as UiApi } from "./types-BgVaFqhF.mjs";
3
+ import { N as InputApi } from "./types-GbVNkvJ4.mjs";
4
+ import { t as HeadlessApp } from "./headless-U4E0LOq0.mjs";
5
+ import { n as Command, r as ControlApp } from "./types--0ZwljWq.mjs";
6
6
 
7
7
  //#region src/plugins/flow/doors/commands.d.ts
8
8
  /**
@@ -1,7 +1,7 @@
1
- import { t as HeadlessApp } from "./headless-1e3gEF1Y.mjs";
2
- import { i as InputArguments, n as Command, o as InputSchema, s as Ran } from "./types-gQATSj41.mjs";
3
- import { t as commands } from "./commands-DLk06fiL.mjs";
4
- import { t as defineCommand } from "./define-CgU4dz0e.mjs";
1
+ import { t as HeadlessApp } from "./headless-U4E0LOq0.mjs";
2
+ import { i as InputArguments, n as Command, o as InputSchema, s as Ran } from "./types--0ZwljWq.mjs";
3
+ import { t as commands } from "./commands-D8GHxQD8.mjs";
4
+ import { t as defineCommand } from "./define-DSl-sLvA.mjs";
5
5
 
6
6
  //#region src/plugins/flow/doors/dev.d.ts
7
7
  /**
@@ -1,5 +1,5 @@
1
- import { t as HeadlessApp } from "./headless-1e3gEF1Y.mjs";
2
- import { c as Source, n as Command, o as InputSchema } from "./types-gQATSj41.mjs";
1
+ import { t as HeadlessApp } from "./headless-U4E0LOq0.mjs";
2
+ import { c as Source, n as Command, o as InputSchema } from "./types--0ZwljWq.mjs";
3
3
 
4
4
  //#region src/plugins/flow/doors/define.d.ts
5
5
  /**
@@ -1,4 +1,4 @@
1
- import { Jr as Api, Ln as Api$1, Or as Json, Vr as RngState, lr as RouteStep, or as FlowState, sr as JournalEntry, vr as Answer } from "./types-DrkR03nL.mjs";
1
+ import { Jr as Api, Ln as Api$1, Or as Json, Vr as RngState, lr as RouteStep, or as FlowState, sr as JournalEntry, vr as Answer } from "./types-iOQUUB2R.mjs";
2
2
 
3
3
  //#region src/plugins/flow/headless.d.ts
4
4
  /**
@@ -1,6 +1,6 @@
1
- import { $n as FeatureDescription, $r as ThermalReading, An as NumericFields, Ar as State$5, B as ShapeValue, Bn as EmitterIdOf, Br as RngApi, C as SceneSpec, Cn as TagType, Cr as State$2, Dt as PassKind, En as Ease, Er as Config$5, F as NineSliceValue, Gn as TextStylesOf, Gr as PauseReason, Hn as HudKeysOf, Hr as Api$3, Jn as defineFlow, Jr as Api$5, K as TransformValue, Kr as State$4, L as OverlayValue, Ln as Api$2, Mn as ProjectionSpec, Mr as Patch, N as HudPartValue, Nn as ReducedMotion, Or as Json, Qr as State$8, Rn as BundlesOf, S as SceneDefinition, Sn as SystemFor, T as State$7, Tn as DescriptionNode, U as SpriteOptions, Ur as Config$4, Vn as GameTypes, W as SpriteValue, Wn as State$3, Wr as Events, X as Config$6, Y as Api$4, Yr as Config$8, Zr as RateChange, _ as AnySceneProjection, _n as Mut, _t as FrameRing, a as Config$1, an as State$9, bn as ResourceType, c as LoadBundles, dt as ViewportSize, er as FeaturePlugin, f as ReadyBundles, fn as ComponentType, fr as Descriptor, gr as Hint, gt as FrameRecord, hr as GuideOptions, i as BundleSpec, ii as Require, ir as DefineNode, jn as ProjectionMotion, kr as Root, l as LoadReason, m as Tier, mr as EffectOptions, ni as Config$10, nn as Api$6, o as DefineBundles, p as State$1, pn as ComponentValue, pr as Effect, q as sprite, r as BundleMap, ri as Events$1, rn as Config$9, rt as State$6, t as Api, tr as FeatureTree, u as LoadResult, un as ComponentHandle, ur as SceneIdOf, v as Config$7, vn as Narrowed, vr as Answer, w as ScenesApi, x as LayerMap, xn as SystemDefinition, xr as Config$2, y as DefineScene, yn as QueryTerm, yr as Api$1, zn as Config$3, zr as StoreApi } from "./types-DrkR03nL.mjs";
2
- import { A as GlowValue, B as Target, C as BlurValue, D as FilterComponent, F as AnimPlayerValue, H as HapticKind, I as Config$11, K as defineAnimation, L as FramesValue, M as OutlineValue, N as UniformDeclaration, O as FilterSpec, P as AnimApi, Q as play, R as MotionKeyframe, S as AlphaValue, T as DisplacementValue, U as SfxDescriptor, W as Step, _ as State$12, a as AudioApi, b as EmitterDefinition, c as MusicDescriptor, d as State$11, f as VolumesFor, h as EffectsApi, j as NoiseValue, k as FilterValueOf, l as MusicOptions, lt as OverlayApi, m as Config$13, n as State$13, r as UiApi, s as Config$12, t as Config$14, w as ColorMatrixValue, x as EmitterValue, y as EmitterConfig, z as State$10 } from "./types-B-o8Ul1v.mjs";
3
- import { B as Message, C as State$16, D as TextStyleInput, G as TypedTr, H as State$14, I as Argument, J as ResolvedStyle, L as Config$15, M as Config$16, N as InputApi, O as TextStyles, P as State$15, R as I18nApi, S as Point, T as TextBind, V as Part, W as TextKey, Y as Style, Z as WhenFlags, b as Config$17, g as IntrinsicElementsFor, h as defineTokens, j as defineComponent, k as TextValue, q as IsFlags, s as PopupComponent, v as BindField, w as TextApi, x as CountdownValue, y as BindOptions, z as IntlKit } from "./types-CFEtGENK.mjs";
1
+ import { $n as FeatureDescription, $r as ThermalReading, An as NumericFields, Ar as State$5, B as ShapeValue, Bn as EmitterIdOf, Br as RngApi, C as SceneSpec, Cn as TagType, Cr as State$2, Dt as PassKind, En as Ease, Er as Config$5, F as NineSliceValue, Gn as TextStylesOf, Gr as PauseReason, Hn as HudKeysOf, Hr as Api$3, Jn as defineFlow, Jr as Api$5, K as TransformValue, Kr as State$4, L as OverlayValue, Ln as Api$2, Mn as ProjectionSpec, Mr as Patch, N as HudPartValue, Nn as ReducedMotion, Or as Json, Qr as State$8, Rn as BundlesOf, S as SceneDefinition, Sn as SystemFor, T as State$7, Tn as DescriptionNode, U as SpriteOptions, Ur as Config$4, Vn as GameTypes, W as SpriteValue, Wn as State$3, Wr as Events, X as Config$6, Y as Api$4, Yr as Config$8, Zr as RateChange, _ as AnySceneProjection, _n as Mut, _t as FrameRing, a as Config$1, an as State$9, bn as ResourceType, c as LoadBundles, dt as ViewportSize, er as FeaturePlugin, f as ReadyBundles, fn as ComponentType, fr as Descriptor, gr as Hint, gt as FrameRecord, hr as GuideOptions, i as BundleSpec, ii as Require, ir as DefineNode, jn as ProjectionMotion, kr as Root, l as LoadReason, m as Tier, mr as EffectOptions, ni as Config$10, nn as Api$6, o as DefineBundles, p as State$1, pn as ComponentValue, pr as Effect, q as sprite, r as BundleMap, ri as Events$1, rn as Config$9, rt as State$6, t as Api, tr as FeatureTree, u as LoadResult, un as ComponentHandle, ur as SceneIdOf, v as Config$7, vn as Narrowed, vr as Answer, w as ScenesApi, x as LayerMap, xn as SystemDefinition, xr as Config$2, y as DefineScene, yn as QueryTerm, yr as Api$1, zn as Config$3, zr as StoreApi } from "./types-iOQUUB2R.mjs";
2
+ import { A as GlowValue, B as Target, C as BlurValue, D as FilterComponent, F as AnimPlayerValue, H as HapticKind, I as Config$11, K as defineAnimation, L as FramesValue, M as OutlineValue, N as UniformDeclaration, O as FilterSpec, P as AnimApi, Q as play, R as MotionKeyframe, S as AlphaValue, T as DisplacementValue, U as SfxDescriptor, W as Step, _ as State$12, a as AudioApi, b as EmitterDefinition, c as MusicDescriptor, d as State$11, f as VolumesFor, h as EffectsApi, j as NoiseValue, k as FilterValueOf, l as MusicOptions, lt as OverlayApi, m as Config$13, n as State$13, r as UiApi, s as Config$12, t as Config$14, w as ColorMatrixValue, x as EmitterValue, y as EmitterConfig, z as State$10 } from "./types-BgVaFqhF.mjs";
3
+ import { B as Message, C as State$16, D as TextStyleInput, G as TypedTr, H as State$14, I as Argument, J as ResolvedStyle, L as Config$15, M as Config$16, N as InputApi, O as TextStyles, P as State$15, R as I18nApi, S as Point, T as TextBind, V as Part, W as TextKey, Y as Style, Z as WhenFlags, b as Config$17, g as IntrinsicElementsFor, h as defineTokens, j as defineComponent, k as TextValue, q as IsFlags, s as PopupComponent, v as BindField, w as TextApi, x as CountdownValue, y as BindOptions, z as IntlKit } from "./types-GbVNkvJ4.mjs";
4
4
  import { Log } from "@moku-labs/common/browser";
5
5
  import { PluginCtx } from "@moku-labs/core";
6
6
 
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { $t as ShaderWhat, At as PerfChange, Bt as PerfLongFrameLine, Ct as PERF_CAUSES, Dt as PassKind, E as types_d_exports$13, Et as PROBLEM_RULES, Ft as PerfEventLine, G as Transform, Gt as PerfStartupLine, H as SpriteBlend, Ht as PerfMeasured, I as Overlay, Ir as SaveUnreadableError, It as PerfEventName, J as AdaptiveScale, Jt as PoolTrimDetail, Kn as types_d_exports$6, Kt as PerfTelemetryLine, L as OverlayValue, Lt as PerfGapLine, M as HudPart, Mt as PerfCollectorLine, N as HudPartValue, Nt as PerfCounts, Ot as PassRecord, P as NineSlice, Pt as PerfDisplay, Qn as type, Qt as ShaderEventDetail, R as Parent, Rt as PerfHeaderLine, St as OverlayWhat, Tn as DescriptionNode, Tt as PERF_LOG_VERSION, Ut as PerfSampleLine, V as Sprite, Vt as PerfMarkLine, Wt as PerfSpikeLine, Xn as slot, Xt as ProblemRule, Yn as exit, Yt as ProblemEventDetail, Z as MonitorConfig, Zn as to, Zt as SHADER_WHATS, _t as FrameRing, at as types_d_exports$12, bt as MonitorSections, en as WarmDetail, g as types_d_exports$1, gt as FrameRecord, ht as FrameReadout, j as Display, jr as types_d_exports$10, jt as PerfChangeEntry, kt as PerfCause, mt as FrameReadResult, nt as PoolTrim, on as types_d_exports$17, pt as FrameColumns, q as sprite, qn as contribution, qr as types_d_exports$9, qt as PerfThermalLine, st as MonitorCounts, ti as types_d_exports$15, tn as DEMAND_REASONS, vt as LongFrameEntry, wr as types_d_exports$3, wt as PERF_GAP_BUCKETS, xt as OverlayEventDetail, yt as MONITOR_SECTIONS, z as Shape, zt as PerfLogLine } from "./types-DrkR03nL.mjs";
2
- import { $ as sequence, E as FilterArea, G as HAPTIC_KINDS, H as HapticKind, J as frames, K as defineAnimation, Q as play, V as types_d_exports, X as mark, Y as haptic, Z as parallel, at as stopSfx, ct as wait, et as set, i as types_d_exports$16, it as stagger, nt as spawn, ot as tween, p as types_d_exports$2, q as external, rt as spawned, st as use, tt as sfx, ut as types_d_exports$4, v as types_d_exports$5 } from "./types-B-o8Ul1v.mjs";
3
- import { A as types_d_exports$14, E as TextFormat, F as types_d_exports$8, K as types_d_exports$7, d as DebugTrigger, f as LocalWrite, h as defineTokens, j as defineComponent, m as popup, p as ScrollState, u as Box, x as CountdownValue, y as BindOptions } from "./types-CFEtGENK.mjs";
4
- import { $ as system, A as Draggable, At as Text, B as Touchable, C as AnimPlayer, Ct as debugPlugin, D as defineBundles, Dt as animPlugin, E as defineScene, Et as assetsPlugin, F as PointerOver, G as Exiting, H as Traced, I as Pressable, J as Order, K as Layer, L as Pressed, M as Held, Mt as defineTextStyles, N as Hovered, Nt as label, O as load, Ot as projection, P as Pointer, Q as resource, R as Swipeable, S as defineMotion, St as effectsPlugin, T as Frames, Tt as audioPlugin, U as PASS_KINDS, V as Traceable, W as frameAt, X as component, Y as Tree, Z as mut, _ as defineStyle, _t as modelPlugin, a as defineEmitter, at as defineFeature, b as messageDuration, bt as i18nPlugin, c as Alpha, ct as uiPlugin, d as Displacement, dt as scenesPlugin, et as tag, f as Glow, ft as rendererPlugin, g as resolve, gt as types_d_exports$11, h as music, ht as PlatformProvider, i as screen, it as schedule, j as DropTarget, jt as bind, k as ready, kt as Countdown, l as Blur, lt as timePlugin, m as Outline, mt as BackResult, n as createPlugin, nt as guide, o as Emitter, ot as flattenFeatures, p as Noise, pt as platformPlugin, q as Now, r as defineGame, rt as hint, s as defineFilter, st as worldPlugin, t as createApp, tt as defineEffect, u as ColorMatrix, ut as textPlugin, v as tr, vt as lifecyclePlugin, w as Animation, wt as clockPlugin, x as cubicBezier, xt as flowPlugin, y as messageArgument, yt as inputPlugin, z as Tappable } from "./index-D12s9KZ2.mjs";
1
+ import { $t as ShaderWhat, At as PerfChange, Bt as PerfLongFrameLine, Ct as PERF_CAUSES, Dt as PassKind, E as types_d_exports$13, Et as PROBLEM_RULES, Ft as PerfEventLine, G as Transform, Gt as PerfStartupLine, H as SpriteBlend, Ht as PerfMeasured, I as Overlay, Ir as SaveUnreadableError, It as PerfEventName, J as AdaptiveScale, Jt as PoolTrimDetail, Kn as types_d_exports$6, Kt as PerfTelemetryLine, L as OverlayValue, Lt as PerfGapLine, M as HudPart, Mt as PerfCollectorLine, N as HudPartValue, Nt as PerfCounts, Ot as PassRecord, P as NineSlice, Pt as PerfDisplay, Qn as type, Qt as ShaderEventDetail, R as Parent, Rt as PerfHeaderLine, St as OverlayWhat, Tn as DescriptionNode, Tt as PERF_LOG_VERSION, Ut as PerfSampleLine, V as Sprite, Vt as PerfMarkLine, Wt as PerfSpikeLine, Xn as slot, Xt as ProblemRule, Yn as exit, Yt as ProblemEventDetail, Z as MonitorConfig, Zn as to, Zt as SHADER_WHATS, _t as FrameRing, at as types_d_exports$12, bt as MonitorSections, en as WarmDetail, g as types_d_exports$1, gt as FrameRecord, ht as FrameReadout, j as Display, jr as types_d_exports$10, jt as PerfChangeEntry, kt as PerfCause, mt as FrameReadResult, nt as PoolTrim, on as types_d_exports$17, pt as FrameColumns, q as sprite, qn as contribution, qr as types_d_exports$9, qt as PerfThermalLine, st as MonitorCounts, ti as types_d_exports$15, tn as DEMAND_REASONS, vt as LongFrameEntry, wr as types_d_exports$3, wt as PERF_GAP_BUCKETS, xt as OverlayEventDetail, yt as MONITOR_SECTIONS, z as Shape, zt as PerfLogLine } from "./types-iOQUUB2R.mjs";
2
+ import { $ as sequence, E as FilterArea, G as HAPTIC_KINDS, H as HapticKind, J as frames, K as defineAnimation, Q as play, V as types_d_exports, X as mark, Y as haptic, Z as parallel, at as stopSfx, ct as wait, et as set, i as types_d_exports$16, it as stagger, nt as spawn, ot as tween, p as types_d_exports$2, q as external, rt as spawned, st as use, tt as sfx, ut as types_d_exports$4, v as types_d_exports$5 } from "./types-BgVaFqhF.mjs";
3
+ import { A as types_d_exports$14, E as TextFormat, F as types_d_exports$8, K as types_d_exports$7, d as DebugTrigger, f as LocalWrite, h as defineTokens, j as defineComponent, m as popup, p as ScrollState, u as Box, x as CountdownValue, y as BindOptions } from "./types-GbVNkvJ4.mjs";
4
+ import { $ as system, A as Draggable, At as Text, B as Touchable, C as AnimPlayer, Ct as debugPlugin, D as defineBundles, Dt as animPlugin, E as defineScene, Et as assetsPlugin, F as PointerOver, G as Exiting, H as Traced, I as Pressable, J as Order, K as Layer, L as Pressed, M as Held, Mt as defineTextStyles, N as Hovered, Nt as label, O as load, Ot as projection, P as Pointer, Q as resource, R as Swipeable, S as defineMotion, St as effectsPlugin, T as Frames, Tt as audioPlugin, U as PASS_KINDS, V as Traceable, W as frameAt, X as component, Y as Tree, Z as mut, _ as defineStyle, _t as modelPlugin, a as defineEmitter, at as defineFeature, b as messageDuration, bt as i18nPlugin, c as Alpha, ct as uiPlugin, d as Displacement, dt as scenesPlugin, et as tag, f as Glow, ft as rendererPlugin, g as resolve, gt as types_d_exports$11, h as music, ht as PlatformProvider, i as screen, it as schedule, j as DropTarget, jt as bind, k as ready, kt as Countdown, l as Blur, lt as timePlugin, m as Outline, mt as BackResult, n as createPlugin, nt as guide, o as Emitter, ot as flattenFeatures, p as Noise, pt as platformPlugin, q as Now, r as defineGame, rt as hint, s as defineFilter, st as worldPlugin, t as createApp, tt as defineEffect, u as ColorMatrix, ut as textPlugin, v as tr, vt as lifecyclePlugin, w as Animation, wt as clockPlugin, x as cubicBezier, xt as flowPlugin, y as messageArgument, yt as inputPlugin, z as Tappable } from "./index-Cerx_CN_.mjs";
5
5
  export { type AdaptiveScale, Alpha, types_d_exports as Anim, AnimPlayer, Animation, types_d_exports$1 as Assets, types_d_exports$2 as Audio, type BackResult, type BindOptions, Blur, Box, types_d_exports$3 as Clock, ColorMatrix, Countdown, type CountdownValue, DEMAND_REASONS, types_d_exports$4 as Debug, DebugTrigger, type DescriptionNode, Displacement, Display, Draggable, DropTarget, types_d_exports$5 as Effects, Emitter, Exiting, type FilterArea, types_d_exports$6 as Flow, type FrameColumns, type FrameReadResult, type FrameReadout, type FrameRecord, type FrameRing, Frames, Glow, HAPTIC_KINDS, type HapticKind, Held, Hovered, HudPart, type HudPartValue, types_d_exports$7 as I18n, types_d_exports$8 as Input, Layer, types_d_exports$9 as Lifecycle, LocalWrite, type LongFrameEntry, MONITOR_SECTIONS, types_d_exports$10 as Model, type MonitorConfig, type MonitorCounts, type MonitorSections, NineSlice, Noise, Now, Order, Outline, Overlay, type OverlayEventDetail, type OverlayValue, type OverlayWhat, PASS_KINDS, PERF_CAUSES, PERF_GAP_BUCKETS, PERF_LOG_VERSION, PROBLEM_RULES, Parent, type PassKind, type PassRecord, type PerfCause, type PerfChange, type PerfChangeEntry, type PerfCollectorLine, type PerfCounts, type PerfDisplay, type PerfEventLine, type PerfEventName, type PerfGapLine, type PerfHeaderLine, type PerfLogLine, type PerfLongFrameLine, type PerfMarkLine, type PerfMeasured, type PerfSampleLine, type PerfSpikeLine, type PerfStartupLine, type PerfTelemetryLine, type PerfThermalLine, types_d_exports$11 as Platform, type PlatformProvider, Pointer, PointerOver, type PoolTrim, type PoolTrimDetail, Pressable, Pressed, type ProblemEventDetail, type ProblemRule, types_d_exports$12 as Renderer, SHADER_WHATS, SaveUnreadableError, types_d_exports$13 as Scenes, ScrollState, type ShaderEventDetail, type ShaderWhat, Shape, Sprite, type SpriteBlend, Swipeable, Tappable, Text, type TextFormat, types_d_exports$14 as TextTypes, types_d_exports$15 as Time, Touchable, Traceable, Traced, Transform, Tree, types_d_exports$16 as Ui, type WarmDetail, types_d_exports$17 as World, animPlugin, assetsPlugin, audioPlugin, bind, clockPlugin, component, contribution, createApp, createPlugin, cubicBezier, debugPlugin, defineAnimation, defineBundles, defineComponent, defineEffect, defineEmitter, defineFeature, defineFilter, defineGame, defineMotion, defineScene, defineStyle, defineTextStyles, defineTokens, effectsPlugin, exit, external, flattenFeatures, flowPlugin, frameAt, frames, guide, haptic, hint, i18nPlugin, inputPlugin, label, lifecyclePlugin, load, mark, messageArgument, messageDuration, modelPlugin, music, mut, parallel, platformPlugin, play, popup, projection, ready, rendererPlugin, resolve, resource, scenesPlugin, schedule, screen, sequence, set, sfx, slot, spawn, spawned, sprite, stagger, stopSfx, system, tag, textPlugin, timePlugin, to, tr, tween, type, uiPlugin, use, wait, worldPlugin };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as sfx, $t as flowPlugin, A as types_exports$7, At as Glow, B as defineMotion, Bt as Animation, C as types_exports$14, Ct as messageDuration, D as types_exports$10, Dt as Blur, E as types_exports$11, Et as Alpha, F as types_exports$2, Ft as audioPlugin, G as external, Gt as MONITOR_SECTIONS, H as platformPlugin, Ht as rendererPlugin, I as types_exports$1, It as scenesPlugin, J as mark, Jt as PERF_LOG_VERSION, K as frames, Kt as PERF_CAUSES, L as types_exports, Lt as assetsPlugin, M as types_exports$5, Mt as Outline, N as types_exports$4, Nt as defineFilter, O as types_exports$9, Ot as ColorMatrix, P as types_exports$3, Pt as debugPlugin, Q as set, Qt as worldPlugin, R as uiPlugin, Rt as animPlugin, S as types_exports$15, St as messageArgument, T as types_exports$12, Tt as Emitter, U as HAPTIC_KINDS, Ut as PASS_KINDS, V as textPlugin, Vt as Frames, W as defineAnimation, Wt as frameAt, X as play, Xt as SHADER_WHATS, Y as parallel, Yt as PROBLEM_RULES, Z as sequence, Zt as DEMAND_REASONS, _ as defineBundles, _t as Tappable, a as cubicBezier, an as type, at as use, b as types_exports$17, bt as Traced, c as hint, cn as lifecyclePlugin, ct as Draggable, d as defineScene, dt as Hovered, et as spawn, f as tr, ft as Pointer, g as music, gt as Swipeable, h as defineEmitter, ht as Pressed, i as screen, in as to, it as tween, j as types_exports$6, jt as Noise, k as types_exports$8, kt as Displacement, l as schedule, ln as timePlugin, lt as DropTarget, m as flattenFeatures, mt as Pressable, n as createPlugin, nn as exit, nt as stagger, o as defineEffect, on as modelPlugin, ot as wait, p as defineFeature, pt as PointerOver, q as haptic, qt as PERF_GAP_BUCKETS, r as defineGame, rn as slot, rt as stopSfx, s as guide, sn as SaveUnreadableError, st as inputPlugin, t as createApp, tn as contribution, tt as spawned, u as projection, un as clockPlugin, ut as Held, v as load, vt as Touchable, w as types_exports$13, wt as effectsPlugin, x as types_exports$16, xt as i18nPlugin, y as ready, yt as Traceable, z as resolve, zt as AnimPlayer } from "./src-Bf1HeSRg.mjs";
1
+ import { $ as sfx, $t as flowPlugin, A as types_exports$7, At as Glow, B as defineMotion, Bt as Animation, C as types_exports$14, Ct as messageDuration, D as types_exports$10, Dt as Blur, E as types_exports$11, Et as Alpha, F as types_exports$2, Ft as audioPlugin, G as external, Gt as MONITOR_SECTIONS, H as platformPlugin, Ht as rendererPlugin, I as types_exports$1, It as scenesPlugin, J as mark, Jt as PERF_LOG_VERSION, K as frames, Kt as PERF_CAUSES, L as types_exports, Lt as assetsPlugin, M as types_exports$5, Mt as Outline, N as types_exports$4, Nt as defineFilter, O as types_exports$9, Ot as ColorMatrix, P as types_exports$3, Pt as debugPlugin, Q as set, Qt as worldPlugin, R as uiPlugin, Rt as animPlugin, S as types_exports$15, St as messageArgument, T as types_exports$12, Tt as Emitter, U as HAPTIC_KINDS, Ut as PASS_KINDS, V as textPlugin, Vt as Frames, W as defineAnimation, Wt as frameAt, X as play, Xt as SHADER_WHATS, Y as parallel, Yt as PROBLEM_RULES, Z as sequence, Zt as DEMAND_REASONS, _ as defineBundles, _t as Tappable, a as cubicBezier, an as type, at as use, b as types_exports$17, bt as Traced, c as hint, cn as lifecyclePlugin, ct as Draggable, d as defineScene, dt as Hovered, et as spawn, f as tr, ft as Pointer, g as music, gt as Swipeable, h as defineEmitter, ht as Pressed, i as screen, in as to, it as tween, j as types_exports$6, jt as Noise, k as types_exports$8, kt as Displacement, l as schedule, ln as timePlugin, lt as DropTarget, m as flattenFeatures, mt as Pressable, n as createPlugin, nn as exit, nt as stagger, o as defineEffect, on as modelPlugin, ot as wait, p as defineFeature, pt as PointerOver, q as haptic, qt as PERF_GAP_BUCKETS, r as defineGame, rn as slot, rt as stopSfx, s as guide, sn as SaveUnreadableError, st as inputPlugin, t as createApp, tn as contribution, tt as spawned, u as projection, un as clockPlugin, ut as Held, v as load, vt as Touchable, w as types_exports$13, wt as effectsPlugin, x as types_exports$16, xt as i18nPlugin, y as ready, yt as Traceable, z as resolve, zt as AnimPlayer } from "./src-oM78C1_G.mjs";
2
2
  import { $ as component, H as Shape, I as Display, J as Exiting, L as HudPart, Q as Tree, R as NineSlice, S as bind, T as label, U as Sprite, V as Parent, W as Transform, X as Now, Y as Layer, Z as Order, b as Countdown, d as LocalWrite, et as mut, g as popup, it as tag, l as DebugTrigger, nt as system, p as ScrollState, q as sprite, s as Box, tt as resource, v as defineTokens, w as defineTextStyles, x as Text, y as defineStyle, z as Overlay } from "./visual-ClVRMUAi.mjs";
3
3
  import { t as defineComponent } from "./component-DGg5DqKK.mjs";
4
4
  export { Alpha, types_exports as Anim, AnimPlayer, Animation, types_exports$1 as Assets, types_exports$2 as Audio, Blur, Box, types_exports$3 as Clock, ColorMatrix, Countdown, DEMAND_REASONS, types_exports$4 as Debug, DebugTrigger, Displacement, Display, Draggable, DropTarget, types_exports$5 as Effects, Emitter, Exiting, types_exports$6 as Flow, Frames, Glow, HAPTIC_KINDS, Held, Hovered, HudPart, types_exports$7 as I18n, types_exports$8 as Input, Layer, types_exports$9 as Lifecycle, LocalWrite, MONITOR_SECTIONS, types_exports$10 as Model, NineSlice, Noise, Now, Order, Outline, Overlay, PASS_KINDS, PERF_CAUSES, PERF_GAP_BUCKETS, PERF_LOG_VERSION, PROBLEM_RULES, Parent, types_exports$11 as Platform, Pointer, PointerOver, Pressable, Pressed, types_exports$12 as Renderer, SHADER_WHATS, SaveUnreadableError, types_exports$13 as Scenes, ScrollState, Shape, Sprite, Swipeable, Tappable, Text, types_exports$14 as TextTypes, types_exports$15 as Time, Touchable, Traceable, Traced, Transform, Tree, types_exports$16 as Ui, types_exports$17 as World, animPlugin, assetsPlugin, audioPlugin, bind, clockPlugin, component, contribution, createApp, createPlugin, cubicBezier, debugPlugin, defineAnimation, defineBundles, defineComponent, defineEffect, defineEmitter, defineFeature, defineFilter, defineGame, defineMotion, defineScene, defineStyle, defineTextStyles, defineTokens, effectsPlugin, exit, external, flattenFeatures, flowPlugin, frameAt, frames, guide, haptic, hint, i18nPlugin, inputPlugin, label, lifecyclePlugin, load, mark, messageArgument, messageDuration, modelPlugin, music, mut, parallel, platformPlugin, play, popup, projection, ready, rendererPlugin, resolve, resource, scenesPlugin, schedule, screen, sequence, set, sfx, slot, spawn, spawned, sprite, stagger, stopSfx, system, tag, textPlugin, timePlugin, to, tr, tween, type, uiPlugin, use, wait, worldPlugin };
@@ -1,9 +1,9 @@
1
- import { Lr as Snapshot, Tr as Api, Un as Position, Y as Api$2, ar as FlowGraph, ct as RenderStats, dn as ComponentSchema, gn as FrameDiff, h as Usage, hn as EntitySnapshot, in as Explained, it as Under, nn as Api$1, sr as JournalEntry, t as Api$3 } from "./types-DrkR03nL.mjs";
2
- import { a as AudioApi, g as EffectsStats, h as EffectsApi, r as UiApi, u as SoundEntry } from "./types-B-o8Ul1v.mjs";
3
- import { c as UiNode } from "./types-CFEtGENK.mjs";
4
- import { t as HeadlessApp } from "./headless-1e3gEF1Y.mjs";
5
- import { a as InputOf, c as Source, i as InputArguments, l as WatchApp, o as InputSchema, t as CheatEntry, u as WatchInput } from "./types-gQATSj41.mjs";
6
- import { n as defineSource } from "./define-CgU4dz0e.mjs";
1
+ import { Lr as Snapshot, Tr as Api, Un as Position, Y as Api$2, ar as FlowGraph, ct as RenderStats, dn as ComponentSchema, gn as FrameDiff, h as Usage, hn as EntitySnapshot, in as Explained, it as Under, nn as Api$1, sr as JournalEntry, t as Api$3 } from "./types-iOQUUB2R.mjs";
2
+ import { a as AudioApi, g as EffectsStats, h as EffectsApi, r as UiApi, u as SoundEntry } from "./types-BgVaFqhF.mjs";
3
+ import { c as UiNode } from "./types-GbVNkvJ4.mjs";
4
+ import { t as HeadlessApp } from "./headless-U4E0LOq0.mjs";
5
+ import { a as InputOf, c as Source, i as InputArguments, l as WatchApp, o as InputSchema, t as CheatEntry, u as WatchInput } from "./types--0ZwljWq.mjs";
6
+ import { n as defineSource } from "./define-DSl-sLvA.mjs";
7
7
 
8
8
  //#region src/plugins/flow/doors/read.d.ts
9
9
  /**
@@ -1,2 +1,2 @@
1
- import { a as jsxs, i as jsxDEV, n as JSX, r as jsx, t as Fragment } from "./runtime-Bpg0WmM8.mjs";
1
+ import { a as jsxs, i as jsxDEV, n as JSX, r as jsx, t as Fragment } from "./runtime-D1cxQae3.mjs";
2
2
  export { Fragment, type JSX, jsx, jsxDEV, jsxs };
@@ -1,2 +1,2 @@
1
- import { a as jsxs, n as JSX, r as jsx, t as Fragment } from "./runtime-Bpg0WmM8.mjs";
1
+ import { a as jsxs, n as JSX, r as jsx, t as Fragment } from "./runtime-D1cxQae3.mjs";
2
2
  export { Fragment, type JSX, jsx, jsxs };
@@ -1,4 +1,4 @@
1
- import { _ as UiIntrinsicElements, a as JsxChild, t as DescriptionNode } from "./types-CFEtGENK.mjs";
1
+ import { _ as UiIntrinsicElements, a as JsxChild, t as DescriptionNode } from "./types-GbVNkvJ4.mjs";
2
2
 
3
3
  //#region src/plugins/ui/jsx/runtime.d.ts
4
4
  /** What the compiler passes as props: the children plus whatever the tag declared. */
@@ -4406,8 +4406,12 @@ function acceptBookmark(ctx, modules, bookmark) {
4406
4406
  }
4407
4407
  //#endregion
4408
4408
  //#region src/plugins/flow/runner/loop-types.ts
4409
- /** The stages of entering a node, in the order they run. */
4410
- const stages = ["load", "scene"];
4409
+ /** The stages of entering a node, in the order they run: what reacts at once, the loads, the scene. */
4410
+ const stages = [
4411
+ "begin",
4412
+ "load",
4413
+ "scene"
4414
+ ];
4411
4415
  /**
4412
4416
  * Does nothing. It stands in for an unsubscribe function until the real one arrives.
4413
4417
  *
@@ -4890,15 +4894,16 @@ function handleFailure(ctx, modules, transaction, error, path, safe) {
4890
4894
  }
4891
4895
  /**
4892
4896
  * Leaves the aborted node: the transaction is discarded, the hints are dropped and the gate is
4893
- * shut. `"stop"` ends the loop; `"restore"` lets the next turn enter the bookmark.
4897
+ * shut. `"stop"` ends the loop; `"restore"` lets the next turn enter the bookmark. A node aborted
4898
+ * in its stages has no transaction yet.
4894
4899
  *
4895
4900
  * @param modules - Injected sibling APIs.
4896
- * @param transaction - The open transaction of the aborted node.
4901
+ * @param transaction - The open transaction of the aborted node, `undefined` during its stages.
4897
4902
  * @param reason - Why the node was aborted.
4898
4903
  * @returns `"stop"` when the runner was stopped, `"continue"` otherwise.
4899
4904
  */
4900
4905
  function handleAbort(modules, transaction, reason) {
4901
- transaction.discard();
4906
+ transaction?.discard();
4902
4907
  modules.fx.drop();
4903
4908
  modules.gate.close();
4904
4909
  return reason === "stop" ? "stop" : "continue";
@@ -5349,7 +5354,9 @@ function nodeInfo(path, location, node) {
5349
5354
  };
5350
5355
  }
5351
5356
  /**
5352
- * Runs the `onEnter` callbacks stage by stage, registration order inside a stage, each awaited.
5357
+ * Runs the `onEnter` callbacks stage by stage (`begin`, `load`, `scene`), registration order inside
5358
+ * a stage, each awaited. A node aborted meanwhile starts no further stage: a restore during
5359
+ * `begin` loads nothing for the node it left.
5353
5360
  *
5354
5361
  * @param ctx - Domain context of the flow plugin.
5355
5362
  * @param info - The node being entered.
@@ -5358,6 +5365,7 @@ function nodeInfo(path, location, node) {
5358
5365
  async function runEnterCallbacks(ctx, info, signal) {
5359
5366
  const mode = ctx.state.fx.mode;
5360
5367
  for (const stage of stages) {
5368
+ if (signal.aborted) return;
5361
5369
  const callbacks = [...ctx.state.runner.enterCallbacks[stage]];
5362
5370
  for (const callback of callbacks) await callback(info, {
5363
5371
  mode,
@@ -5373,15 +5381,37 @@ async function runEnterCallbacks(ctx, info, signal) {
5373
5381
  * @example
5374
5382
  * ```ts
5375
5383
  * abortReason(AbortSignal.abort("inbox")); // "inbox"
5384
+ * abortReason(AbortSignal.abort("failed")); // "failed": a stage of the node threw
5376
5385
  * abortReason(AbortSignal.abort()); // "stop": anything unexpected
5377
5386
  * ```
5378
5387
  */
5379
5388
  function abortReason(signal) {
5380
5389
  const reason = signal.reason;
5381
- if (reason === "inbox" || reason === "restore") return reason;
5390
+ if (reason === "inbox" || reason === "restore" || reason === "failed") return reason;
5382
5391
  return "stop";
5383
5392
  }
5384
5393
  /**
5394
+ * Tells whether a stage rejected because its node was aborted: with an `AbortError` (the wait of a
5395
+ * download that a stop or a restore cancelled) or with the signal's own reason. A real error that
5396
+ * arrives after the abort is still a failure of the node.
5397
+ *
5398
+ * @param signal - The node's abort signal.
5399
+ * @param error - What the stage rejected with.
5400
+ * @returns True when the rejection is the abort itself.
5401
+ * @example
5402
+ * ```ts
5403
+ * const aborted = AbortSignal.abort("restore");
5404
+ * const cancelled = Object.assign(new Error("[game] assets: the load was aborted."), { name: "AbortError" });
5405
+ * isAbortRejection(aborted, cancelled); // true
5406
+ * isAbortRejection(aborted, new Error("offline")); // false: a real failure
5407
+ * ```
5408
+ */
5409
+ function isAbortRejection(signal, error) {
5410
+ if (!signal.aborted) return false;
5411
+ if (error === signal.reason) return true;
5412
+ return error instanceof Error && error.name === "AbortError";
5413
+ }
5414
+ /**
5385
5415
  * Tells whether the runner was stopped. The abort of `onStop` survives between two nodes, so a
5386
5416
  * loop that is not inside a node ends at the next turn.
5387
5417
  *
@@ -5838,6 +5868,8 @@ async function runNode(ctx, modules, location, node, safe) {
5838
5868
  try {
5839
5869
  await runEnterCallbacks(ctx, nodeInfo(path, location, node), abort.signal);
5840
5870
  } catch (error) {
5871
+ if (isAbortRejection(abort.signal, error)) return handleAbort(modules, void 0, abortReason(abort.signal));
5872
+ abort.abort("failed");
5841
5873
  return handleFailure(ctx, modules, void 0, error, path, safe);
5842
5874
  }
5843
5875
  const step = {
@@ -6949,6 +6981,7 @@ function createRunnerState() {
6949
6981
  flushing: void 0,
6950
6982
  flows: emptyFlows(),
6951
6983
  enterCallbacks: {
6984
+ begin: [],
6952
6985
  load: [],
6953
6986
  scene: []
6954
6987
  },
@@ -11269,6 +11302,8 @@ function reseedViews(state, name, from, to) {
11269
11302
  }
11270
11303
  //#endregion
11271
11304
  //#region src/plugins/world/projection/reconcile.ts
11305
+ /** The components of a view of the build at its spawn: none, so it is flagged before the first `onAdded`. */
11306
+ const NO_COMPONENTS = [];
11272
11307
  /**
11273
11308
  * Creates the empty set of used hints. It lives in its own non-exported function because lint
11274
11309
  * rule L5 refuses a collection built inside an exported declaration.
@@ -11337,8 +11372,8 @@ function hintFor$1(pctx, projection, key, used) {
11337
11372
  * play the `enter` hook and the `loop` hook when the reconcile plays motions. The loop is not
11338
11373
  * kept with the view's handles: a change cancels those, and the loop runs until the view dies.
11339
11374
  * A direct reconcile plays neither hook. The view then owes its loop, which the sweep starts.
11340
- * A view of a projection the running build mounts is flagged building right after its spawn: the
11341
- * spawn fires `onAdded` inside the call, so no flag can come before it.
11375
+ * A view of a projection the running build mounts is spawned bare, flagged building, then given
11376
+ * its components in the same order: the `onAdded` hooks of a plugin then tell it apart (F97).
11342
11377
  *
11343
11378
  * @param pctx - Domain context of the projection module.
11344
11379
  * @param spec - The projection spec.
@@ -11352,18 +11387,26 @@ function hintFor$1(pctx, projection, key, used) {
11352
11387
  */
11353
11388
  function enterEntry(pctx, spec, mounted, entry) {
11354
11389
  const values = collectView(pctx, spec, entry.item);
11355
- const entity = pctx.deps.ecs.spawn({
11390
+ const state = pctx.ctx.state.projection;
11391
+ const building = state.building;
11392
+ const ecs = pctx.deps.ecs;
11393
+ const owner = {
11356
11394
  kind: "projection",
11357
11395
  name: spec.name
11358
- }, [pctx.deps.components.Layer({ name: spec.layer }), ...values.values()]);
11396
+ };
11397
+ const layer = pctx.deps.components.Layer({ name: spec.layer });
11398
+ let entity;
11399
+ if (building?.mounted.get(spec.name) === mounted) {
11400
+ entity = ecs.spawn(owner, NO_COMPONENTS);
11401
+ building.entities.add(entity);
11402
+ ecs.add(entity, layer);
11403
+ for (const value of values.values()) ecs.add(entity, value);
11404
+ } else entity = ecs.spawn(owner, [layer, ...values.values()]);
11359
11405
  const view = createViewRecord(entity, spec.name, entry.key, entry.item, values, entry.direct ? "mount" : "change");
11360
- const state = pctx.ctx.state.projection;
11361
- const building = state.building;
11362
11406
  seedMutes(state, spec, entity);
11363
11407
  mounted.live.set(entry.key, view);
11364
11408
  state.byEntity.set(entity, view);
11365
11409
  state.membershipVersion += 1;
11366
- if (building?.mounted.get(spec.name) === mounted) building.entities.add(entity);
11367
11410
  const hook = spec.motion?.enter;
11368
11411
  const loop = spec.motion?.loop;
11369
11412
  if (entry.direct) {
@@ -39964,7 +40007,7 @@ function leftScene(ctx, run) {
39964
40007
  /**
39965
40008
  * Shows the veil and the loader of a switch that starts now, before its bundles are awaited: the scene being left
39966
40009
  * decides. A loader projection is mounted only once its loader is due. An abort of the node drops both at once, from
39967
- * its listener.
40010
+ * its listener. The look keeps the node's signal, so the `scene` stage of the same node takes it over.
39968
40011
  *
39969
40012
  * @param ctx - Domain context of the plugin.
39970
40013
  * @param scene - The scene being switched to.
@@ -39978,6 +40021,8 @@ function startLeave(ctx, scene, run) {
39978
40021
  if (leave === void 0) return void 0;
39979
40022
  const listening = new AbortController();
39980
40023
  const leaving = {
40024
+ signal: run.signal,
40025
+ to: scene.id,
39981
40026
  done: false,
39982
40027
  off: () => listening.abort()
39983
40028
  };
@@ -39996,6 +40041,44 @@ function startLeave(ctx, scene, run) {
39996
40041
  return leaving;
39997
40042
  }
39998
40043
  /**
40044
+ * The look the `begin` stage of this node started: its `scene` stage takes it over instead of starting a second one.
40045
+ *
40046
+ * @param ctx - Domain context of the plugin.
40047
+ * @param run - The runner's mode and signal of the node.
40048
+ * @returns The running look of this node, or `undefined`.
40049
+ */
40050
+ function ownLeave(ctx, run) {
40051
+ const leaving = ctx.state.leaving;
40052
+ return leaving?.signal === run.signal ? leaving : void 0;
40053
+ }
40054
+ /**
40055
+ * The look the `begin` stage of this node started for the scene the `scene` stage switches to. One it started for
40056
+ * another scene (the expected scene changed between the two stages) is dropped: its loader was resolved against that
40057
+ * scene, so the switch shows its own.
40058
+ *
40059
+ * @param ctx - Domain context of the plugin.
40060
+ * @param run - The runner's mode and signal of the node.
40061
+ * @param target - The scene the switch mounts.
40062
+ * @returns The look to take over, or `undefined` when the switch shows its own.
40063
+ */
40064
+ function leaveFor(ctx, run, target) {
40065
+ const own = ownLeave(ctx, run);
40066
+ if (own === void 0 || own.to === target) return own;
40067
+ endLeave(ctx, own, "drop");
40068
+ }
40069
+ /**
40070
+ * Drops a look still running when another node is entered: the node that started it never reached its swap. Flow aborts
40071
+ * a node whose stage threw (a download that failed), so the abort listener drops such a look already, before the
40072
+ * rollback; this is the backstop for a node that ended without an abort the look heard.
40073
+ *
40074
+ * @param ctx - Domain context of the plugin.
40075
+ * @param run - The runner's mode and signal of the node being entered.
40076
+ */
40077
+ function dropLeftOver(ctx, run) {
40078
+ const leaving = ctx.state.leaving;
40079
+ if (leaving !== void 0 && leaving.signal !== run.signal) endLeave(ctx, leaving, "drop");
40080
+ }
40081
+ /**
39999
40082
  * Ends the look of a switch once: `"land"` at the swap (the loader goes, the veil fades out over the next scene),
40000
40083
  * `"drop"` on an abort or a throw (both go at once). A loader projection mounted for the wait is unmounted. A look
40001
40084
  * ended already, or a switch that showed nothing, is left alone.
@@ -40402,10 +40485,12 @@ async function loadAndStand(ctx, scene, named, run) {
40402
40485
  await standUp(ctx, scene, named, run);
40403
40486
  }
40404
40487
  /**
40405
- * Switches to another scene: it reads what the scene names from the committed state, shows the
40406
- * veil and the loader of the scene being left at once (a cold first visit reacts in the next
40407
- * frame), then awaits the bundles and builds the scene (`loadAndStand`). The look lands when the
40408
- * scene stands, and is dropped when the switch ends without it or throws.
40488
+ * Switches to another scene: it takes over the veil and the loader the `begin` stage of the node
40489
+ * showed over the scene being left for this scene (a cold first visit reacts in the next frame),
40490
+ * or shows them now when that stage did not, or showed them for another scene, after reading what
40491
+ * the scene names from the committed state. Then
40492
+ * it awaits the bundles and builds the scene (`loadAndStand`). The look lands when the scene
40493
+ * stands, and is dropped when the switch ends without it or throws.
40409
40494
  *
40410
40495
  * @param ctx - Domain context of the plugin.
40411
40496
  * @param target - Id of the scene to mount.
@@ -40416,10 +40501,10 @@ async function loadAndStand(ctx, scene, named, run) {
40416
40501
  async function switchTo(ctx, target, run) {
40417
40502
  const scene = ctx.state.scenes.get(target);
40418
40503
  if (scene === void 0) throw new Error(`[game] Scene "${target}" is not registered.\n List it in the scenes of a feature.`);
40419
- const named = namedBundles(scene, committedState(ctx));
40420
- let leaving;
40504
+ let leaving = leaveFor(ctx, run, scene.id);
40421
40505
  try {
40422
- leaving = startLeave(ctx, scene, run);
40506
+ const named = namedBundles(scene, committedState(ctx));
40507
+ leaving ??= startLeave(ctx, scene, run);
40423
40508
  await loadAndStand(ctx, scene, named, run);
40424
40509
  } catch (error) {
40425
40510
  endLeave(ctx, leaving, "drop");
@@ -40470,15 +40555,51 @@ async function enterScene(ctx, node, run) {
40470
40555
  await switchTo(ctx, target, run);
40471
40556
  return;
40472
40557
  }
40558
+ endLeave(ctx, ownLeave(ctx, run), "drop");
40473
40559
  if (isFastTransit(node, run)) return;
40474
40560
  await reread(ctx, run);
40475
40561
  }
40562
+ /**
40563
+ * Reads the scene the `scene` stage of the node will switch to, by the rules of `targetOf` and
40564
+ * `overTargetOf`, without touching the record: an over node takes the expected scene, any other
40565
+ * node its own scene or else the expected one. A transit node of a fast walk switches nothing.
40566
+ *
40567
+ * @param ctx - Domain context of the plugin.
40568
+ * @param node - The node being entered.
40569
+ * @param run - The runner's mode and signal.
40570
+ * @returns The scene id the node asks for, or `undefined`.
40571
+ */
40572
+ function nextScene(ctx, node, run) {
40573
+ if (isFastTransit(node, run)) return void 0;
40574
+ if (node.over) return ctx.state.pending;
40575
+ return node.scene ?? ctx.state.pending;
40576
+ }
40577
+ /**
40578
+ * The `begin` stage of entering a node, which must not wait (spec 33, slice A3): a node that
40579
+ * switches to another scene shows the look of the scene being left now, before the `load` stage
40580
+ * downloads the bundles of the coming one, so a cold first visit reacts in the next frame. The
40581
+ * `scene` stage of the same node takes the look over, lands it at the swap or drops it. A node
40582
+ * that keeps the scene, the first scene of a run, a fast walk and an aborted node start nothing
40583
+ * (`startLeave` decides the rest). A stage after `begin` that throws aborts the node, and the abort
40584
+ * drops the look; one a node before left running all the same is dropped first.
40585
+ *
40586
+ * @param ctx - Domain context of the plugin.
40587
+ * @param node - The node being entered.
40588
+ * @param run - The runner's mode and signal.
40589
+ */
40590
+ function beginScene(ctx, node, run) {
40591
+ dropLeftOver(ctx, run);
40592
+ const target = nextScene(ctx, node, run);
40593
+ if (target === void 0 || target === ctx.state.current) return;
40594
+ const scene = ctx.state.scenes.get(target);
40595
+ if (scene !== void 0) startLeave(ctx, scene, run);
40596
+ }
40476
40597
  //#endregion
40477
40598
  //#region src/plugins/scenes/lifecycle.ts
40478
40599
  /**
40479
40600
  * @file scenes plugin — lifecycle: the config checked in `onInit`, the scenes read out of the
40480
- * feature descriptions in `onStart`, the one `onEnter` registration, and the teardown that removes
40481
- * exactly that registration.
40601
+ * feature descriptions in `onStart`, the two `onEnter` registrations (`begin` and `scene`), and the
40602
+ * teardown that removes exactly those registrations.
40482
40603
  */
40483
40604
  /**
40484
40605
  * Resolves the dependency APIs `flow`, `world`, `assets`, `time`, `model` and `renderer` with
@@ -40555,8 +40676,9 @@ function checkConfig(config) {
40555
40676
  throw new Error(`[game] scenes.buildMs is ${String(value)}.\n Give "auto" or the milliseconds a frame may spend on the next scene, a finite number above 0 such as 4.`);
40556
40677
  }
40557
40678
  /**
40558
- * Starts the plugin in `onStart`: it collects the scenes of the features and registers the one
40559
- * callback that switches them, on the `scene` stage of entering a node.
40679
+ * Starts the plugin in `onStart`: it collects the scenes of the features and registers two
40680
+ * callbacks of entering a node: at `begin` the look of the scene being left, before `assets`
40681
+ * downloads anything at `load`, and at `scene` the switch.
40560
40682
  *
40561
40683
  * @param ctx - Kernel context of the scenes plugin.
40562
40684
  * @throws {Error} When two features declare the same scene id.
@@ -40569,10 +40691,16 @@ function checkConfig(config) {
40569
40691
  function startScenes(ctx) {
40570
40692
  const scenes = withDeps$5(ctx);
40571
40693
  readScenes(scenes);
40572
- scenes.state.teardown = scenes.deps.flow.onEnter("scene", (node, run) => enterScene(scenes, node, run));
40694
+ const flow = scenes.deps.flow;
40695
+ const offBegin = flow.onEnter("begin", (node, run) => beginScene(scenes, node, run));
40696
+ const offScene = flow.onEnter("scene", (node, run) => enterScene(scenes, node, run));
40697
+ scenes.state.teardown = () => {
40698
+ offBegin();
40699
+ offScene();
40700
+ };
40573
40701
  }
40574
40702
  /**
40575
- * Removes the `onEnter` callback in `onStop` and forgets every scene and the bundles the mounted
40703
+ * Removes the two `onEnter` callbacks in `onStop` and forgets every scene and the bundles the mounted
40576
40704
  * one named. A running build loses its frame callback and its switch returns; the look of a running
40577
40705
  * switch loses its abort listener (the renderer drops it at its own stop). Nothing is unmounted
40578
40706
  * or discarded: a teardown context may not call another plugin, and `world.onStop` clears every
@@ -1,7 +1,7 @@
1
- import { Or as Json, Sr as FakeClock, _r as NodeFx, br as ClockSource, cr as NodeTable, er as FeaturePlugin, fr as Descriptor, gr as Hint, nr as AnyFlow } from "./types-DrkR03nL.mjs";
2
- import { t as createApp } from "./index-D12s9KZ2.mjs";
3
- import { b as saveOf, v as WithGameState, y as memory } from "./types-DQ9VHXun.mjs";
4
- import { a as createHeadless, i as ReproResult, n as HeadlessGame, o as runRepro, r as Repro, s as stepFrames, t as HeadlessApp } from "./headless-1e3gEF1Y.mjs";
1
+ import { Or as Json, Sr as FakeClock, _r as NodeFx, br as ClockSource, cr as NodeTable, er as FeaturePlugin, fr as Descriptor, gr as Hint, nr as AnyFlow } from "./types-iOQUUB2R.mjs";
2
+ import { t as createApp } from "./index-Cerx_CN_.mjs";
3
+ import { b as saveOf, v as WithGameState, y as memory } from "./types-CtpKlJTd.mjs";
4
+ import { a as createHeadless, i as ReproResult, n as HeadlessGame, o as runRepro, r as Repro, s as stepFrames, t as HeadlessApp } from "./headless-U4E0LOq0.mjs";
5
5
  import { AnyPluginInstance } from "@moku-labs/core";
6
6
 
7
7
  //#region src/plugins/clock/fake.d.ts
package/dist/testing.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { an as type, en as refuseStart, m as flattenFeatures, nn as exit, t as createApp } from "./src-Bf1HeSRg.mjs";
1
+ import { an as type, en as refuseStart, m as flattenFeatures, nn as exit, t as createApp } from "./src-oM78C1_G.mjs";
2
2
  import { n as saveOf, t as memory } from "./memory-CWlqhS7l.mjs";
3
3
  import { n as fakeClock } from "./fake-hnJcJeYf.mjs";
4
4
  import { i as stepFrames, r as runRepro, t as createHeadless } from "./headless-CCiUwvlp.mjs";
@@ -1,5 +1,5 @@
1
- import { Lr as Snapshot, Or as Json } from "./types-DrkR03nL.mjs";
2
- import { t as HeadlessApp } from "./headless-1e3gEF1Y.mjs";
1
+ import { Lr as Snapshot, Or as Json } from "./types-iOQUUB2R.mjs";
2
+ import { t as HeadlessApp } from "./headless-U4E0LOq0.mjs";
3
3
  import { Log } from "@moku-labs/common/browser";
4
4
 
5
5
  //#region src/plugins/flow/doors/types.d.ts
@@ -1,5 +1,5 @@
1
- import { $ as PixiModule, A as SyncApi, An as NumericFields, Dr as Events$3, En as Ease, Fn as TrackSegment, Jr as Api$1, Ln as Api$2, Nn as ReducedMotion, O as FilterSlot, Or as Json, Pn as TrackOptions, Q as PixiFilter, Tr as Api$6, Wr as Events$5, Y as Api$4, b as Events$4, dr as TypeTag, et as PixiSprite, fn as ComponentType, fr as Descriptor, ft as FilterCache, ii as Require, k as FilterSlotInputs, kn as MotionHandle, ln as AnyComponentValue, mn as Entity, nn as Api$3, ri as Events$2, s as Events$1, sn as AnyComponent, t as Api$5, tt as PixiTexture, un as ComponentHandle, ut as Point } from "./types-DrkR03nL.mjs";
2
- import { N as InputApi, R as I18nApi, X as StylesState, c as UiNode, i as Finding, l as LayoutState, n as ElementChange, o as JsxState, r as ElementMotion, w as TextApi } from "./types-CFEtGENK.mjs";
1
+ import { $ as PixiModule, A as SyncApi, An as NumericFields, Dr as Events$3, En as Ease, Fn as TrackSegment, Jr as Api$1, Ln as Api$2, Nn as ReducedMotion, O as FilterSlot, Or as Json, Pn as TrackOptions, Q as PixiFilter, Tr as Api$6, Wr as Events$5, Y as Api$4, b as Events$4, dr as TypeTag, et as PixiSprite, fn as ComponentType, fr as Descriptor, ft as FilterCache, ii as Require, k as FilterSlotInputs, kn as MotionHandle, ln as AnyComponentValue, mn as Entity, nn as Api$3, ri as Events$2, s as Events$1, sn as AnyComponent, t as Api$5, tt as PixiTexture, un as ComponentHandle, ut as Point } from "./types-iOQUUB2R.mjs";
2
+ import { N as InputApi, R as I18nApi, X as StylesState, c as UiNode, i as Finding, l as LayoutState, n as ElementChange, o as JsxState, r as ElementMotion, w as TextApi } from "./types-GbVNkvJ4.mjs";
3
3
  import { Log } from "@moku-labs/common/browser";
4
4
  import { PluginCtx } from "@moku-labs/core";
5
5
 
@@ -1,7 +1,7 @@
1
- import { $ as PixiModule, Er as Config, Fr as SaveDoc, Nr as PlayerStateProvider, Or as Json, Pr as ProviderCall, Rr as SnapshotOf, Sr as FakeClock, X as Config$2, a as Config$3, br as ClockSource, d as Manifest, dr as TypeTag, er as FeaturePlugin, lt as Orientation, n as AssetsIo, nr as AnyFlow, zn as Config$1 } from "./types-DrkR03nL.mjs";
2
- import { o as AudioContextLike, s as Config$4 } from "./types-B-o8Ul1v.mjs";
3
- import { R as I18nApi, U as StringTable, W as TextKey } from "./types-CFEtGENK.mjs";
4
- import { St as effectsPlugin, Tt as audioPlugin, ht as PlatformProvider, i as screen, pt as platformPlugin, t as createApp } from "./index-D12s9KZ2.mjs";
1
+ import { $ as PixiModule, Er as Config, Fr as SaveDoc, Nr as PlayerStateProvider, Or as Json, Pr as ProviderCall, Rr as SnapshotOf, Sr as FakeClock, X as Config$2, a as Config$3, br as ClockSource, d as Manifest, dr as TypeTag, er as FeaturePlugin, lt as Orientation, n as AssetsIo, nr as AnyFlow, zn as Config$1 } from "./types-iOQUUB2R.mjs";
2
+ import { o as AudioContextLike, s as Config$4 } from "./types-BgVaFqhF.mjs";
3
+ import { R as I18nApi, U as StringTable, W as TextKey } from "./types-GbVNkvJ4.mjs";
4
+ import { St as effectsPlugin, Tt as audioPlugin, ht as PlatformProvider, i as screen, pt as platformPlugin, t as createApp } from "./index-Cerx_CN_.mjs";
5
5
  import { AnyPluginInstance } from "@moku-labs/core";
6
6
 
7
7
  //#region src/plugins/model/store/providers/memory.d.ts
@@ -1,4 +1,4 @@
1
- import { An as NumericFields, Cn as TagType, Dn as Motion, En as Ease, In as ViewHandle, Jr as Api, K as TransformValue, Ln as Api$1, Nn as ReducedMotion, On as MotionCause, Or as Json, Y as Api$3, cn as AnyComponentType, dt as ViewportSize, fn as ComponentType, fr as Descriptor, gr as Hint, ii as Require, jn as ProjectionMotion, kn as MotionHandle, ln as AnyComponentValue, mn as Entity, nn as Api$2, s as Events$1, sn as AnyComponent, t as Api$4, vr as Answer, wn as ChangeHook, yr as Api$5 } from "./types-DrkR03nL.mjs";
1
+ import { An as NumericFields, Cn as TagType, Dn as Motion, En as Ease, In as ViewHandle, Jr as Api, K as TransformValue, Ln as Api$1, Nn as ReducedMotion, On as MotionCause, Or as Json, Y as Api$3, cn as AnyComponentType, dt as ViewportSize, fn as ComponentType, fr as Descriptor, gr as Hint, ii as Require, jn as ProjectionMotion, kn as MotionHandle, ln as AnyComponentValue, mn as Entity, nn as Api$2, s as Events$1, sn as AnyComponent, t as Api$4, vr as Answer, wn as ChangeHook, yr as Api$5 } from "./types-iOQUUB2R.mjs";
2
2
  import { Log } from "@moku-labs/common/browser";
3
3
  import { PluginCtx } from "@moku-labs/core";
4
4
  import { Node, Yoga } from "yoga-layout/load";
@@ -3086,14 +3086,23 @@ type FlowState = {
3086
3086
  mode: "live" | "fast";
3087
3087
  };
3088
3088
  /**
3089
- * Stages of entering a node: `assets` preloads at `load`, `scenes` switches at `scene`.
3089
+ * Stages of entering a node, in the order they run: `begin`, `load`, `scene`. At `begin` a plugin
3090
+ * starts what reacts at once and returns without waiting: the loop awaits it before the `load`
3091
+ * stage, so a callback that waits there delays the loads. `assets` preloads at `load`, `scenes`
3092
+ * switches at `scene`.
3090
3093
  *
3091
3094
  * @example
3092
3095
  * ```ts
3093
- * const stage: Stage = "load";
3096
+ * // Registered in any order, the stages of a node run begin, load, scene: the veil `scenes` shows
3097
+ * // at "begin" is up before `assets` downloads the board at "load".
3098
+ * const order: string[] = [];
3099
+ * app.flow.onEnter("scene", () => order.push("scene"));
3100
+ * app.flow.onEnter("load", () => order.push("load"));
3101
+ * app.flow.onEnter("begin", () => order.push("begin"));
3102
+ * // entering a node: order is ["begin", "load", "scene"]
3094
3103
  * ```
3095
3104
  */
3096
- type Stage = "load" | "scene";
3105
+ type Stage = "begin" | "load" | "scene";
3097
3106
  /**
3098
3107
  * Callback of `onEnter`. Called before `node.run`, awaited. Read the state with
3099
3108
  * `model.store.snapshot()`: no node of the graph writes while the stages run.
@@ -3208,9 +3217,18 @@ type RunnerApi = {
3208
3217
  */
3209
3218
  run(): Promise<void>;
3210
3219
  /**
3211
- * Registers a callback run before every node body: `assets` preloads at `load`, `scenes`
3212
- * switches at `scene`. Every `load` callback runs before the first `scene` callback, in
3213
- * registration order, each awaited.
3220
+ * Registers a callback run before every node body, at one of three stages: `scenes` reacts at
3221
+ * `begin` (the veil over the scene being left), `assets` preloads at `load`, `scenes` switches
3222
+ * at `scene`. Every `begin` callback runs before the first `load` callback, and every `load`
3223
+ * callback before the first `scene` callback, in registration order inside a stage, each
3224
+ * awaited. A `begin` callback must not wait: it starts what reacts at once and returns, since
3225
+ * the loads start only after it. Once the node is aborted (a restore, a stop) no further stage
3226
+ * starts. A stage that throws ends the node: its signal is aborted with reason `"failed"` before
3227
+ * the rollback, so what an earlier stage started for it (a veil over the scene being left) is
3228
+ * taken down at once, also before a safe node's `recover` and when the failure is fatal. A stage
3229
+ * that rejects with the abort itself after a stop or a restore (the `AbortError` of a cancelled
3230
+ * download, or the signal's reason) is that abort, not a failure: no rollback, no `flow:error`.
3231
+ * A real error that arrives after the abort is still a failure.
3214
3232
  *
3215
3233
  * The stages run before the node opens its transaction, and `model.store.snapshot()` is the
3216
3234
  * committed state, so a stage reads the state the node is entered with: on an ordinary entry
@@ -3219,15 +3237,24 @@ type RunnerApi = {
3219
3237
  * its `recover` committed, or, without `recover`, the state of the rest point the rollback
3220
3238
  * returned to.
3221
3239
  *
3222
- * @param stage - `"load"` or `"scene"`.
3240
+ * @param stage - `"begin"`, `"load"` or `"scene"`.
3223
3241
  * @param callback - Called with the node and `{ mode, signal }`, awaited.
3224
3242
  * @returns The unregister function.
3225
3243
  * @example
3226
3244
  * ```ts
3227
- * // A scenes plugin switches the screen when the graph enters a node.
3228
- * const off = app.flow.onEnter("scene", node => showScene(node.path)); // node.path: "home"
3245
+ * // The scenes plugin, at the tap on "board" over the ward: the veil goes up at `begin`, without
3246
+ * // waiting, while the `load` stage still downloads the board; the switch runs at `scene`.
3247
+ * const flow = ctx.require(flowPlugin);
3248
+ * const veil = { cover: { color: 0x000000, alpha: 0.45, inMs: 150, outMs: 150 } };
3249
+ * const offBegin = flow.onEnter("begin", (node, { mode }) => {
3250
+ * if (mode === "live" && node.scene === "board") ctx.require(rendererPlugin).sync.leave.show(veil);
3251
+ * });
3252
+ * const offScene = flow.onEnter("scene", async node => {
3253
+ * // node.scene: "board": await its bundles, build it aside, swap it in, then land the veil
3254
+ * });
3229
3255
  *
3230
- * off(); // the plugin stops: the callback is not called any more
3256
+ * offBegin(); // the plugin stops: neither callback is called any more
3257
+ * offScene();
3231
3258
  * ```
3232
3259
  */
3233
3260
  onEnter(stage: Stage, callback: EnterCallback): () => void;
@@ -3300,7 +3327,7 @@ type RunnerApi = {
3300
3327
  * ended the loop, or `run()` rejected. Nothing is entered then and the state is not replaced.
3301
3328
  * `state()` shows whether it was: its `path` is the node the graph stands at.
3302
3329
  *
3303
- * The restored node's `load` and `scene` stages run after this resolves for a rest node: the
3330
+ * The restored node's `begin`, `load` and `scene` stages run after this resolves for a rest node: the
3304
3331
  * scene is mounted when its bundles are in, before the node's gate opens;
3305
3332
  * `await app.flow.walk([])` waits for that gate.
3306
3333
  *
@@ -5175,8 +5202,9 @@ type ProjectionApi = {
5175
5202
  */
5176
5203
  left(): number;
5177
5204
  /**
5178
- * Whether an entity belongs to the running build: a view it spawned, or an entity `adopt` marked. One set lookup;
5179
- * false with no build and after the commit. Allocates nothing.
5205
+ * Whether an entity belongs to the running build: a view it spawned, or an entity `adopt` marked. A view is flagged
5206
+ * before the `onAdded` hooks of its components, so a hook can ask. One set lookup; false with no build and after the
5207
+ * commit. Allocates nothing.
5180
5208
  *
5181
5209
  * @param entity - The entity to ask about.
5182
5210
  * @returns True for an entity of the running build.
@@ -5186,6 +5214,11 @@ type ProjectionApi = {
5186
5214
  * const projection = ctx.require(worldPlugin).projection;
5187
5215
  * projection.isBuilding(1_048_600); // true: a board item the build spawned
5188
5216
  * projection.isBuilding(1_048_576); // false: a ward bed on screen
5217
+ *
5218
+ * // A game plugin keeps one camera root: the root of the scene built aside is not a second one.
5219
+ * ctx.require(worldPlugin).ecs.onAdded(Pan, entity => {
5220
+ * if (projection.isBuilding(entity)) return; // true for the memory's root, built while the ward shows
5221
+ * });
5189
5222
  * ```
5190
5223
  */
5191
5224
  isBuilding(entity: Entity): boolean;
@@ -12198,7 +12231,7 @@ type State$1 = {
12198
12231
  * is mounted.
12199
12232
  */
12200
12233
  named: readonly string[];
12201
- owner: SceneOwner; /** The remover of the `onEnter` callback: set in `onStart`, run in `onStop`. */
12234
+ owner: SceneOwner; /** The remover of the two `onEnter` callbacks, `begin` and `scene`: set in `onStart`, run in `onStop`. */
12202
12235
  teardown: (() => void) | undefined;
12203
12236
  /**
12204
12237
  * The build of the next scene on a live switch, from its start to its commit or discard.
@@ -12206,17 +12239,28 @@ type State$1 = {
12206
12239
  */
12207
12240
  build?: SceneBuild;
12208
12241
  /**
12209
- * The veil and the loader of the running switch, from its start to its swap or its end without one. Absent
12210
- * otherwise: deleted, never written as `undefined`.
12242
+ * The veil and the loader of the running switch, from the `begin` stage of its node to its swap or its end without
12243
+ * one. Absent otherwise: deleted, never written as `undefined`.
12211
12244
  */
12212
12245
  leaving?: Leaving;
12213
12246
  };
12214
12247
  /**
12215
- * The veil and the loader a switch showed over the scene being left (spec 33, slice A2): whether they were taken down
12216
- * already, the loader projection it mounted once its loader was due, and how to stop listening to the abort of its node.
12248
+ * The veil and the loader a switch showed over the scene being left (spec 33, slices A2 and A3): the node that started
12249
+ * them, whether they were taken down already, the loader projection it mounted once its loader was due, and how to stop
12250
+ * listening to the abort of its node.
12217
12251
  */
12218
12252
  type Leaving = {
12219
- /** Landed or dropped: a second end does nothing. */done: boolean; /** The loader projection the switch mounted, unmounted at the end; absent while it mounted none. */
12253
+ /**
12254
+ * The abort signal of the node whose `begin` stage started the look: its `scene` stage takes the look over, and the
12255
+ * `begin` stage of any later node finds it left over by a node that never reached its `scene` stage.
12256
+ */
12257
+ signal: AbortSignal;
12258
+ /**
12259
+ * The scene the look was started for: the `scene` stage takes it over only for that scene, since its loader was
12260
+ * resolved against it.
12261
+ */
12262
+ to: string; /** Landed or dropped: a second end does nothing. */
12263
+ done: boolean; /** The loader projection the switch mounted, unmounted at the end; absent while it mounted none. */
12220
12264
  projection?: string; /** Removes the abort listener of the switch's node. */
12221
12265
  off: () => void;
12222
12266
  };
@@ -1,9 +1,9 @@
1
- import { Hr as Api$3, Tr as Api$2, Y as Api, nn as Api$1, yr as Api$4 } from "./types-DrkR03nL.mjs";
2
- import { P as AnimApi, r as UiApi } from "./types-B-o8Ul1v.mjs";
3
- import { N as InputApi } from "./types-CFEtGENK.mjs";
4
- import { r as Repro } from "./headless-1e3gEF1Y.mjs";
5
- import { a as InputOf, r as ControlApp } from "./types-gQATSj41.mjs";
6
- import { t as commands } from "./commands-DLk06fiL.mjs";
1
+ import { Hr as Api$3, Tr as Api$2, Y as Api, nn as Api$1, yr as Api$4 } from "./types-iOQUUB2R.mjs";
2
+ import { P as AnimApi, r as UiApi } from "./types-BgVaFqhF.mjs";
3
+ import { N as InputApi } from "./types-GbVNkvJ4.mjs";
4
+ import { r as Repro } from "./headless-U4E0LOq0.mjs";
5
+ import { a as InputOf, r as ControlApp } from "./types--0ZwljWq.mjs";
6
+ import { t as commands } from "./commands-D8GHxQD8.mjs";
7
7
 
8
8
  //#region src/visual/types.d.ts
9
9
  /** The base commands of the `/control` door, keyed by their short names. */
package/dist/visual.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as VisualApp, c as VisualRenderer, d as VisualStart, f as VisualStep, h as VisualTolerance, i as CheckpointResult, l as VisualReport, m as VisualTestResult, n as runVisualTests, o as VisualOptions, p as VisualTest, r as defineVisualTest, s as VisualPage, t as parseVisualArgv, u as VisualSetup } from "./visual-pHKIFBSQ.mjs";
1
+ import { a as VisualApp, c as VisualRenderer, d as VisualStart, f as VisualStep, h as VisualTolerance, i as CheckpointResult, l as VisualReport, m as VisualTestResult, n as runVisualTests, o as VisualOptions, p as VisualTest, r as defineVisualTest, s as VisualPage, t as parseVisualArgv, u as VisualSetup } from "./visual-BYv2iKd3.mjs";
2
2
  export { type CheckpointResult, type VisualApp, type VisualOptions, type VisualPage, type VisualRenderer, type VisualReport, type VisualSetup, type VisualStart, type VisualStep, type VisualTest, type VisualTestResult, type VisualTolerance, defineVisualTest, parseVisualArgv, runVisualTests };
package/llms.txt CHANGED
@@ -509,7 +509,7 @@ The editor's overlay from the game, in every app. The plugin name `debug` is res
509
509
  ### flow (Very Complex, depends on time, lifecycle, model, clock)
510
510
 
511
511
  The graph. Modules `runner`, `gate`, `inbox`, `fx`, `features`. Runner methods sit on the plugin root.
512
- - Runner: `run(): Promise<void>`, `onEnter(stage: "load" | "scene", callback): () => void`, `walk(route, options?: { from?: Bookmark }): Promise<FlowState>`, `bookmark(): Bookmark`, `restore(bookmark): Promise<void>`, `describe(): FlowGraph`, `state(): FlowState`, `history(): readonly JournalEntry[]`, `setMode("live" | "fast")`.
512
+ - Runner: `run(): Promise<void>`, `onEnter(stage: "begin" | "load" | "scene", callback): () => void` (stages run in that order, each awaited; a `"begin"` callback must not wait: `scenes` shows the veil there before `assets` downloads at `"load"`), `walk(route, options?: { from?: Bookmark }): Promise<FlowState>`, `bookmark(): Bookmark`, `restore(bookmark): Promise<void>`, `describe(): FlowGraph`, `state(): FlowState`, `history(): readonly JournalEntry[]`, `setMode("live" | "fast")`.
513
513
  - `gate.answer({ intent, payload? }): boolean` is the one entry of player answers. `gate.pointer(active)`. `gate.state(): { open, allowed, narrowed }`.
514
514
  - `inbox.post({ type, payload? })` queues a world event. One entry per type. It is delivered only to a rest node whose `inbox` lists the type.
515
515
  - `fx.handle(kind, handler, options?: { runInFast?: boolean }): () => void` registers the single handler of one effect kind. `fx.dispatch(descriptor)` is fire-and-forget. An awaited effect without a handler resolves `undefined` at once.
@@ -529,7 +529,7 @@ The graph. Modules `runner`, `gate`, `inbox`, `fx`, `features`. Runner methods s
529
529
  ### Screen plugins (V2, built)
530
530
 
531
531
  `world`, `renderer`, `input`, `assets`, `scenes`. Each has a README at `src/plugins/<name>/README.md`; the root README lists their APIs, events and config. Rendering: WebGPU preferred, with Pixi's WebGL fallback.
532
- - `app.scenes`: `current()` the mounted scene id, `expect(id)` the scene the next node without its own `scene` mounts, a rest node or a transit node in live mode (the restore door calls it; an unknown id throws). An `over` node takes it the same way, also over another mounted scene. A live switch, before it builds the scene, warms the bundles the scene names (`assets.warm`): their textures go to the GPU `renderer.uploads` a drawn frame while the old scene is still up, so the first frame of the new scene uploads none of them; textures already there are not waited for, and a fast walk or a headless app never waits. A bundle the scene does not name (a `core` bundle of portraits the board shows) is not warmed: name it in the scene's `bundles` or call `app.assets.warm`. Then, with a drawing renderer, the next scene is built aside: its ui elements are made by root and by part, laid out once and applied in parts, and the renderer makes its Pixi views, over the next frames off the stage in a budget per frame, config `scenes.buildMs: number | "auto"` (default `"auto"`, two thirds of the frame interval: 11.1 ms at 60 Hz, 5.56 ms at 120 Hz; `0` throws), and it is swapped in one frame. Until the swap `current()` answers the old scene, nothing of the new one is drawn, hit or found by `ui.find`, its `enter` motions wait and the gate stays closed, so the first tap lands on a complete scene; `scenes:changed` is emitted at the swap. A fast walk, a world that is not live and a headless app mount in one block as before.
532
+ - `app.scenes`: `current()` the mounted scene id, `expect(id)` the scene the next node without its own `scene` mounts, a rest node or a transit node in live mode (the restore door calls it; an unknown id throws). An `over` node takes it the same way, also over another mounted scene. A live switch, before it builds the scene, warms the bundles the scene names (`assets.warm`): their textures go to the GPU `renderer.uploads` a drawn frame while the old scene is still up, so the first frame of the new scene uploads none of them; textures already there are not waited for, and a fast walk or a headless app never waits. A bundle the scene does not name (a `core` bundle of portraits the board shows) is not warmed: name it in the scene's `bundles` or call `app.assets.warm`. Then, with a drawing renderer, the next scene is built aside: its ui elements are made by root and by part, laid out once and applied in parts, and the renderer makes its Pixi views, over the next frames off the stage in a budget per frame, config `scenes.buildMs: number | "auto"` (default `"auto"`, two thirds of the frame interval: 11.1 ms at 60 Hz, 5.56 ms at 120 Hz; `0` throws), and it is swapped in one frame. Until the swap `current()` answers the old scene, nothing of the new one is drawn, hit or found by `ui.find`, its `enter` motions wait and the gate stays closed, so the first tap lands on a complete scene; `scenes:changed` is emitted at the swap. A fast walk, a world that is not live and a headless app mount in one block as before. Over the scene being left, a live switch shows the look of `scenes.leave` (a veil, and a loader once the switch is not done `afterMs` after its start); the veil goes up at the node's `"begin"` stage, before `assets` downloads the coming scene at `"load"`, so a cold first visit reacts in the next frame.
533
533
  - `Shape({ kind, w, h, fill, fillAlpha, alpha, radius, stroke, strokeWidth, dash, clip, sweep?, cap? })` (`kind: "rect"`; `sweep` and `cap` are optional, `1` and `"round"` when left out; only an arc reads them; a rectangle or a triangle ignores them, also when an earlier arc left them on the `Shape`): a rounded rectangle, `kind: "triangle"` (fills its box pointing right) or `kind: "arc"`: a stroke on the circle inscribed in the box (`min(w, h) − strokeWidth` across, centred) from 12 o'clock clockwise over `sweep` (0..1, clamped; 0 draws nothing, 1 a closed ring), ended by `cap` (`"round" | "butt"`); an arc draws no fill and ignores `radius` and `dash`. The path is built again only when a field changes: a still arc costs nothing a frame. `Shape({ kind: "arc", w: 28, h: 28, stroke: 0xc8a15a, strokeWidth: 2.2, sweep: 0.42 })` is a slot timer's ring with 42 % left.
534
534
  - Overlays: `Overlay({ dim, dimColor, cover, hud, fade, hold })` on the root of an overlay (in `components`) keeps everything drawn before it as one picture, retaken in the frame anything in it changes, and with `cover: "opaque"` draws none of it once landed at alpha 1; `hold: true` (default `false`) holds the endless loops under it while it stands, as under a cover or a blurred picture (their phase follows time), so a dimmed sheet over a sharp scene draws no frame at rest; the engine draws the dim (`dim × level`, right under the root); the level follows the root's own enter and exit motion, `fade` (250 ms) only when it has none; level and landing are read through `app.renderer.sync.debug.overlays()`. A `backdrop: true` filter inside the kept range runs no pass while the picture stands (its look is in the picture) and is drawn again in the frame the overlay is gone. Types: `OverlayValue` (the component's value) and `HudPartValue` (a part of the HUD an overlay keeps shown or lets fade).
535
535
  - HUD: a scene layer `{ above: "overlays" }` is the HUD layer, drawn above every overlay and never in a picture; a scene with a HUD layer and no `ui` gets `ui` right under it. Its roots never take the keyboard: Escape and the Back press reach the top sheet under it. `HudPart({ key })` tags a HUD view; an overlay's `hud` (`"all"`, `"none"` or keys) names the parts that stay shown, the others fade with its level and take no tap. Keys are typed by `defineGame<{ …, hud: "energy" | "gems" }>()`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moku-labs/game",
3
- "version": "0.15.42",
3
+ "version": "0.15.44",
4
4
  "description": "2D puzzle game engine on TypeScript and PixiJS, built on @moku-labs/core.",
5
5
  "type": "module",
6
6
  "sideEffects": [