@moku-labs/game 0.15.35 → 0.15.37

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.
Files changed (32) hide show
  1. package/dist/app/page.d.mts +1 -1
  2. package/dist/app/system.d.mts +3 -3
  3. package/dist/app.d.mts +3 -3
  4. package/dist/app.mjs +1 -1
  5. package/dist/{assets-B8_Uc6_n.mjs → assets-I-FJDl3W.mjs} +7 -3
  6. package/dist/assets.d.mts +1 -1
  7. package/dist/assets.mjs +1 -1
  8. package/dist/cli.mjs +1 -1
  9. package/dist/{commands-BGrtxBga.d.mts → commands-BZPrVtJT.d.mts} +5 -5
  10. package/dist/control.d.mts +4 -4
  11. package/dist/{define-0af8h-Ro.d.mts → define-T-WIPEkg.d.mts} +2 -2
  12. package/dist/{headless-BFI7EXHo.d.mts → headless-Bx3WG3fZ.d.mts} +1 -1
  13. package/dist/{index-Cs4qaPMq.d.mts → index-BMpWPXvo.d.mts} +9 -7
  14. package/dist/index.d.mts +4 -4
  15. package/dist/index.mjs +1 -1
  16. package/dist/inspect.d.mts +6 -6
  17. package/dist/jsx-dev-runtime.d.mts +1 -1
  18. package/dist/jsx-runtime.d.mts +1 -1
  19. package/dist/{rolldown-runtime-8H4AJuhK.mjs → rolldown-runtime-BhDjJH2R.mjs} +3 -2
  20. package/dist/{runtime-DIOe0nCH.d.mts → runtime-c0miURhi.d.mts} +1 -1
  21. package/dist/{src-C6XBMo4Q.mjs → src-ChniuNDc.mjs} +232 -55
  22. package/dist/testing.d.mts +4 -4
  23. package/dist/testing.mjs +1 -1
  24. package/dist/{types-Dh2cyp0H.d.mts → types-B4G8sOED.d.mts} +4 -4
  25. package/dist/{types-D52biu5v.d.mts → types-B6fvpFoz.d.mts} +2 -2
  26. package/dist/{types-K3qfyTu0.d.mts → types-BCI9vUA6.d.mts} +76 -6
  27. package/dist/{types-B1W2CPUu.d.mts → types-BVSmbgJB.d.mts} +2 -2
  28. package/dist/{types-BAv5qOZX.d.mts → types-k5szXqU1.d.mts} +1 -1
  29. package/dist/{visual-DMx0vv_3.d.mts → visual-D0cotXHi.d.mts} +6 -6
  30. package/dist/visual.d.mts +1 -1
  31. package/llms.txt +1 -0
  32. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { m as StartedPage, r as GameConfig, t as AnyGameApp, u as PageOptions } from "../types-Dh2cyp0H.mjs";
1
+ import { m as StartedPage, r as GameConfig, t as AnyGameApp, u as PageOptions } from "../types-B4G8sOED.mjs";
2
2
 
3
3
  //#region src/app/page.d.ts
4
4
  /**
@@ -1,6 +1,6 @@
1
- import { Mr as PlayerStateProvider } from "../types-K3qfyTu0.mjs";
2
- import { ht as PlatformProvider } from "../index-Cs4qaPMq.mjs";
3
- import { _ as SystemShellFactory, g as SystemName, h as SystemModules } from "../types-Dh2cyp0H.mjs";
1
+ import { Mr as PlayerStateProvider } from "../types-BCI9vUA6.mjs";
2
+ import { ht as PlatformProvider } from "../index-BMpWPXvo.mjs";
3
+ import { _ as SystemShellFactory, g as SystemName, h as SystemModules } from "../types-B4G8sOED.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 { Dr as Json } from "./types-K3qfyTu0.mjs";
2
- import { U as StringTable } from "./types-BAv5qOZX.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-Dh2cyp0H.mjs";
1
+ import { Dr as Json } from "./types-BCI9vUA6.mjs";
2
+ import { U as StringTable } from "./types-k5szXqU1.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-B4G8sOED.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-C6XBMo4Q.mjs";
1
+ import { Ft as audioPlugin, H as platformPlugin, i as screen, m as flattenFeatures, t as createApp, wt as effectsPlugin } from "./src-ChniuNDc.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
@@ -1,3 +1,4 @@
1
+ import { n as __require } from "./rolldown-runtime-BhDjJH2R.mjs";
1
2
  import { t as findFeatureOwners } from "./features-DowEilZm.mjs";
2
3
  import { createRequire } from "node:module";
3
4
  import path from "node:path";
@@ -2174,9 +2175,11 @@ function isRecord(value) {
2174
2175
  }
2175
2176
  /**
2176
2177
  * Imports the optional `assets.ts` of a feature. Node strips the types of a `.ts` file, so the
2177
- * description a game writes runs as it stands. The URL carries the file's size and mtime: a
2178
- * long-lived process (the keys watch of `dev` and the editor) reads a saved description again
2179
- * instead of the module it cached, while one scan, or scans with nothing saved, import it once.
2178
+ * description a game writes runs as it stands. A long-lived process (the keys watch of `dev` and
2179
+ * the editor) must read a saved description again, not the module it imported first. Bun keeps a
2180
+ * module by its path and ignores a query, so the entry is dropped from its cache before each
2181
+ * import; the query (the file's size and mtime) does the same in a module runner that keys by
2182
+ * URL, such as vitest's.
2180
2183
  *
2181
2184
  * @param file - Absolute path of the description.
2182
2185
  * @returns Its exports, or `undefined` when the feature brought none.
@@ -2185,6 +2188,7 @@ function isRecord(value) {
2185
2188
  async function importDescription(file) {
2186
2189
  const entry = await stat(file).catch(() => {});
2187
2190
  if (entry === void 0 || !entry.isFile()) return void 0;
2191
+ if (typeof __require !== "undefined") delete __require.cache[file];
2188
2192
  return await import(
2189
2193
  /* @vite-ignore */
2190
2194
  `${pathToFileURL(file).href}?saved=${entry.size}-${Math.round(entry.mtimeMs * 1e3)}`
package/dist/assets.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { d as Manifest } from "./types-K3qfyTu0.mjs";
1
+ import { d as Manifest } from "./types-BCI9vUA6.mjs";
2
2
 
3
3
  //#region src/plugins/assets/scan/cli.d.ts
4
4
  /**
package/dist/assets.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { a as runCli, c as emitKeys, i as compileStrings, l as emitManifest, n as importStrings, o as scanAssets, r as checkStrings, s as packAssets, t as exportStrings } from "./assets-B8_Uc6_n.mjs";
1
+ import { a as runCli, c as emitKeys, i as compileStrings, l as emitManifest, n as importStrings, o as scanAssets, r as checkStrings, s as packAssets, t as exportStrings } from "./assets-I-FJDl3W.mjs";
2
2
  export { checkStrings, compileStrings, emitKeys, emitManifest, exportStrings, importStrings, packAssets, runCli, scanAssets };
package/dist/cli.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { t as resolveConfig } from "./config-B87aFTW-.mjs";
2
2
  import { t as findFeatureOwners } from "./features-DowEilZm.mjs";
3
3
  import { r as watchTree, t as createBatcher, x as isSkippedFolder$1 } from "./watch-BSgptowj.mjs";
4
- import { a as runCli$1, i as compileStrings, n as importStrings, t as exportStrings } from "./assets-B8_Uc6_n.mjs";
4
+ import { a as runCli$1, i as compileStrings, n as importStrings, t as exportStrings } from "./assets-I-FJDl3W.mjs";
5
5
  import { constants, copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, rmSync, statSync, watch, writeFileSync } from "node:fs";
6
6
  import path from "node:path";
7
7
  import { createBrandConsole } from "@moku-labs/common/cli";
@@ -1,8 +1,8 @@
1
- import { $r as Time, D as DebugSwitches, Ir as Snapshot, Rr as StoreApi, Vr as Api, Y as Api$1, Yr as FrameRate, ar as FlowState, nn as Api$2, nr as Bookmark, ot as Captured, w as ScenesApi } from "./types-K3qfyTu0.mjs";
2
- import { P as AnimApi, a as AudioApi, h as EffectsApi, r as UiApi } from "./types-B1W2CPUu.mjs";
3
- import { N as InputApi } from "./types-BAv5qOZX.mjs";
4
- import { t as HeadlessApp } from "./headless-BFI7EXHo.mjs";
5
- import { n as Command, r as ControlApp } from "./types-D52biu5v.mjs";
1
+ import { $r as Time, D as DebugSwitches, Ir as Snapshot, Rr as StoreApi, Vr as Api, Y as Api$1, Yr as FrameRate, ar as FlowState, nn as Api$2, nr as Bookmark, ot as Captured, w as ScenesApi } from "./types-BCI9vUA6.mjs";
2
+ import { P as AnimApi, a as AudioApi, h as EffectsApi, r as UiApi } from "./types-BVSmbgJB.mjs";
3
+ import { N as InputApi } from "./types-k5szXqU1.mjs";
4
+ import { t as HeadlessApp } from "./headless-Bx3WG3fZ.mjs";
5
+ import { n as Command, r as ControlApp } from "./types-B6fvpFoz.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-BFI7EXHo.mjs";
2
- import { i as InputArguments, n as Command, o as InputSchema, s as Ran } from "./types-D52biu5v.mjs";
3
- import { t as commands } from "./commands-BGrtxBga.mjs";
4
- import { t as defineCommand } from "./define-0af8h-Ro.mjs";
1
+ import { t as HeadlessApp } from "./headless-Bx3WG3fZ.mjs";
2
+ import { i as InputArguments, n as Command, o as InputSchema, s as Ran } from "./types-B6fvpFoz.mjs";
3
+ import { t as commands } from "./commands-BZPrVtJT.mjs";
4
+ import { t as defineCommand } from "./define-T-WIPEkg.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-BFI7EXHo.mjs";
2
- import { c as Source, n as Command, o as InputSchema } from "./types-D52biu5v.mjs";
1
+ import { t as HeadlessApp } from "./headless-Bx3WG3fZ.mjs";
2
+ import { c as Source, n as Command, o as InputSchema } from "./types-B6fvpFoz.mjs";
3
3
 
4
4
  //#region src/plugins/flow/doors/define.d.ts
5
5
  /**
@@ -1,4 +1,4 @@
1
- import { Br as RngState, Dr as Json, Ln as Api$1, _r as Answer, ar as FlowState, cr as RouteStep, or as JournalEntry, qr as Api } from "./types-K3qfyTu0.mjs";
1
+ import { Br as RngState, Dr as Json, Ln as Api$1, _r as Answer, ar as FlowState, cr as RouteStep, or as JournalEntry, qr as Api } from "./types-BCI9vUA6.mjs";
2
2
 
3
3
  //#region src/plugins/flow/headless.d.ts
4
4
  /**
@@ -1,6 +1,6 @@
1
- import { $n as FeaturePlugin, An as NumericFields, B as ShapeValue, Bn as EmitterIdOf, C as SceneSpec, Cn as TagType, Dr as Json, Dt as PassKind, En as Ease, F as NineSliceValue, Gn as TextStylesOf, Gr as State$4, Hn as HudKeysOf, Hr as Config$4, Jr as Config$8, K as TransformValue, L as OverlayValue, Ln as Api$2, Mn as ProjectionSpec, N as HudPartValue, Nn as ReducedMotion, Or as Root, Qn as FeatureDescription, Qr as ThermalReading, Rn as BundlesOf, Rr as StoreApi, S as SceneDefinition, Sn as SystemFor, Sr as State$2, T as State$7, Tn as DescriptionNode, Tr as Config$5, U as SpriteOptions, Ur as Events, Vn as GameTypes, Vr as Api$3, W as SpriteValue, Wn as State$3, Wr as PauseReason, X as Config$6, Xr as RateChange, Y as Api$4, Zr as State$8, _ as AnySceneProjection, _n as Mut, _r as Answer, _t as FrameRing, a as Config$1, an as State$9, bn as ResourceType, br as Config$2, c as LoadBundles, dr as Descriptor, dt as ViewportSize, er as FeatureTree, f as ReadyBundles, fn as ComponentType, fr as Effect, gt as FrameRecord, hr as Hint, i as BundleSpec, jn as ProjectionMotion, jr as Patch, kr as State$5, l as LoadReason, lr as SceneIdOf, m as Tier, mr as GuideOptions, ni as Events$1, nn as Api$6, o as DefineBundles, p as State$1, pn as ComponentValue, pr as EffectOptions, q as sprite, qn as defineFlow, qr as Api$5, r as BundleMap, ri as Require, rn as Config$9, rr as DefineNode, rt as State$6, t as Api, ti as Config$10, u as LoadResult, un as ComponentHandle, v as Config$7, vn as Narrowed, vr as Api$1, w as ScenesApi, x as LayerMap, xn as SystemDefinition, y as DefineScene, yn as QueryTerm, zn as Config$3, zr as RngApi } from "./types-K3qfyTu0.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-B1W2CPUu.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-BAv5qOZX.mjs";
1
+ import { $n as FeaturePlugin, An as NumericFields, B as ShapeValue, Bn as EmitterIdOf, C as SceneSpec, Cn as TagType, Dr as Json, Dt as PassKind, En as Ease, F as NineSliceValue, Gn as TextStylesOf, Gr as State$4, Hn as HudKeysOf, Hr as Config$4, Jr as Config$8, K as TransformValue, L as OverlayValue, Ln as Api$2, Mn as ProjectionSpec, N as HudPartValue, Nn as ReducedMotion, Or as Root, Qn as FeatureDescription, Qr as ThermalReading, Rn as BundlesOf, Rr as StoreApi, S as SceneDefinition, Sn as SystemFor, Sr as State$2, T as State$7, Tn as DescriptionNode, Tr as Config$5, U as SpriteOptions, Ur as Events, Vn as GameTypes, Vr as Api$3, W as SpriteValue, Wn as State$3, Wr as PauseReason, X as Config$6, Xr as RateChange, Y as Api$4, Zr as State$8, _ as AnySceneProjection, _n as Mut, _r as Answer, _t as FrameRing, a as Config$1, an as State$9, bn as ResourceType, br as Config$2, c as LoadBundles, dr as Descriptor, dt as ViewportSize, er as FeatureTree, f as ReadyBundles, fn as ComponentType, fr as Effect, gt as FrameRecord, hr as Hint, i as BundleSpec, jn as ProjectionMotion, jr as Patch, kr as State$5, l as LoadReason, lr as SceneIdOf, m as Tier, mr as GuideOptions, ni as Events$1, nn as Api$6, o as DefineBundles, p as State$1, pn as ComponentValue, pr as EffectOptions, q as sprite, qn as defineFlow, qr as Api$5, r as BundleMap, ri as Require, rn as Config$9, rr as DefineNode, rt as State$6, t as Api, ti as Config$10, u as LoadResult, un as ComponentHandle, v as Config$7, vn as Narrowed, vr as Api$1, w as ScenesApi, x as LayerMap, xn as SystemDefinition, y as DefineScene, yn as QueryTerm, zn as Config$3, zr as RngApi } from "./types-BCI9vUA6.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-BVSmbgJB.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-k5szXqU1.mjs";
4
4
  import { Log } from "@moku-labs/common/browser";
5
5
  import { PluginCtx } from "@moku-labs/core";
6
6
 
@@ -102,9 +102,11 @@ declare function defineTextStyles(map: Record<string, TextStyleInput>): TextStyl
102
102
  /**
103
103
  * Types a projection: keyed items of the model turned into entities. `Item` is inferred from the
104
104
  * return of `from` and reaches `key`, `view` and every motion hook; `layer` and `lift` stay
105
- * literal, so `defineScene` can check them against the layers of the scene.
105
+ * literal, so `defineScene` can check them against the layers of the scene. Each pair of
106
+ * `initialOnly` has its field names checked against its own component.
106
107
  *
107
- * @param spec - Name, layer, optional lift layer, `from`, `key`, `view` and the motion hooks.
108
+ * @param spec - Name, layer, optional lift layer, `from`, `key`, `view`, the motion hooks and
109
+ * the `initialOnly` fields.
108
110
  * @returns The same spec, typed.
109
111
  * @example
110
112
  * ```ts
@@ -118,7 +120,7 @@ declare function defineTextStyles(map: Record<string, TextStyleInput>): TextStyl
118
120
  * boardItems.layer; // "items", the literal type, not string
119
121
  * ```
120
122
  */
121
- declare function projection<const LayerName extends string, const LiftName extends string, Item, Player = Json, Session = Json>(spec: ProjectionSpec<Item, LayerName, LiftName, Player, Session>): ProjectionSpec<Item, LayerName, LiftName, Player, Session>;
123
+ declare function projection<const LayerName extends string, const LiftName extends string, Item, Player = Json, Session = Json, const Values extends readonly object[] = []>(spec: ProjectionSpec<Item, LayerName, LiftName, Player, Session, Values>): ProjectionSpec<Item, LayerName, LiftName, Player, Session, Values>;
122
124
  /**
123
125
  * The projection helper bound to one game's `player` and `session`.
124
126
  *
@@ -127,7 +129,7 @@ declare function projection<const LayerName extends string, const LiftName exten
127
129
  * const bound: ProjectionFor<{ coins: number }, {}> = projection;
128
130
  * ```
129
131
  */
130
- type ProjectionFor<Player, Session> = <const LayerName extends string, const LiftName extends string, Item>(spec: ProjectionSpec<Item, LayerName, LiftName, Player, Session>) => ProjectionSpec<Item, LayerName, LiftName, Player, Session>;
132
+ type ProjectionFor<Player, Session> = <const LayerName extends string, const LiftName extends string, Item, const Values extends readonly object[] = []>(spec: ProjectionSpec<Item, LayerName, LiftName, Player, Session, Values>) => ProjectionSpec<Item, LayerName, LiftName, Player, Session, Values>;
131
133
  //#endregion
132
134
  //#region src/plugins/anim/index.d.ts
133
135
  /**
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { $t as ShaderWhat, Ar as types_d_exports$10, At as PerfChange, Bt as PerfLongFrameLine, Cr as types_d_exports$3, Ct as PERF_CAUSES, Dt as PassKind, E as types_d_exports$13, Et as PROBLEM_RULES, Fr as SaveUnreadableError, Ft as PerfEventLine, G as Transform, Gt as PerfStartupLine, H as SpriteBlend, Ht as PerfMeasured, I as Overlay, It as PerfEventName, J as AdaptiveScale, Jn as exit, Jt as PoolTrimDetail, Kn as types_d_exports$6, Kr as types_d_exports$9, 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, 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 to, Xt as ProblemRule, Yn as slot, Yt as ProblemEventDetail, Z as MonitorConfig, Zn as type, Zt as SHADER_WHATS, _t as FrameRing, at as types_d_exports$12, bt as MonitorSections, ei as types_d_exports$15, en as WarmDetail, g as types_d_exports$1, gt as FrameRecord, ht as FrameReadout, j as Display, jt as PerfChangeEntry, kt as PerfCause, mt as FrameReadResult, nt as PoolTrim, on as types_d_exports$17, pt as FrameColumns, q as sprite, qt as PerfThermalLine, st as MonitorCounts, tn as DEMAND_REASONS, vt as LongFrameEntry, wt as PERF_GAP_BUCKETS, xt as OverlayEventDetail, yt as MONITOR_SECTIONS, z as Shape, zt as PerfLogLine } from "./types-K3qfyTu0.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-B1W2CPUu.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-BAv5qOZX.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-Cs4qaPMq.mjs";
1
+ import { $t as ShaderWhat, Ar as types_d_exports$10, At as PerfChange, Bt as PerfLongFrameLine, Cr as types_d_exports$3, Ct as PERF_CAUSES, Dt as PassKind, E as types_d_exports$13, Et as PROBLEM_RULES, Fr as SaveUnreadableError, Ft as PerfEventLine, G as Transform, Gt as PerfStartupLine, H as SpriteBlend, Ht as PerfMeasured, I as Overlay, It as PerfEventName, J as AdaptiveScale, Jn as exit, Jt as PoolTrimDetail, Kn as types_d_exports$6, Kr as types_d_exports$9, 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, 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 to, Xt as ProblemRule, Yn as slot, Yt as ProblemEventDetail, Z as MonitorConfig, Zn as type, Zt as SHADER_WHATS, _t as FrameRing, at as types_d_exports$12, bt as MonitorSections, ei as types_d_exports$15, en as WarmDetail, g as types_d_exports$1, gt as FrameRecord, ht as FrameReadout, j as Display, jt as PerfChangeEntry, kt as PerfCause, mt as FrameReadResult, nt as PoolTrim, on as types_d_exports$17, pt as FrameColumns, q as sprite, qt as PerfThermalLine, st as MonitorCounts, tn as DEMAND_REASONS, vt as LongFrameEntry, wt as PERF_GAP_BUCKETS, xt as OverlayEventDetail, yt as MONITOR_SECTIONS, z as Shape, zt as PerfLogLine } from "./types-BCI9vUA6.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-BVSmbgJB.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-k5szXqU1.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-BMpWPXvo.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, 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 modelPlugin, at as use, b as types_exports$17, bt as Traced, c as hint, cn as timePlugin, 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 type, it as tween, j as types_exports$6, jt as Noise, k as types_exports$8, kt as Displacement, l as schedule, ln as clockPlugin, lt as DropTarget, m as flattenFeatures, mt as Pressable, n as createPlugin, nn as slot, nt as stagger, o as defineEffect, on as SaveUnreadableError, ot as wait, p as defineFeature, pt as PointerOver, q as haptic, qt as PERF_GAP_BUCKETS, r as defineGame, rn as to, rt as stopSfx, s as guide, sn as lifecyclePlugin, st as inputPlugin, t as createApp, tn as exit, tt as spawned, u as projection, 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-C6XBMo4Q.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 modelPlugin, at as use, b as types_exports$17, bt as Traced, c as hint, cn as timePlugin, 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 type, it as tween, j as types_exports$6, jt as Noise, k as types_exports$8, kt as Displacement, l as schedule, ln as clockPlugin, lt as DropTarget, m as flattenFeatures, mt as Pressable, n as createPlugin, nn as slot, nt as stagger, o as defineEffect, on as SaveUnreadableError, ot as wait, p as defineFeature, pt as PointerOver, q as haptic, qt as PERF_GAP_BUCKETS, r as defineGame, rn as to, rt as stopSfx, s as guide, sn as lifecyclePlugin, st as inputPlugin, t as createApp, tn as exit, tt as spawned, u as projection, 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-ChniuNDc.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, 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 { Ir as Snapshot, Un as Position, Y as Api$2, ct as RenderStats, dn as ComponentSchema, gn as FrameDiff, h as Usage, hn as EntitySnapshot, in as Explained, ir as FlowGraph, it as Under, nn as Api$1, or as JournalEntry, t as Api$3, wr as Api } from "./types-K3qfyTu0.mjs";
2
- import { a as AudioApi, g as EffectsStats, h as EffectsApi, r as UiApi, u as SoundEntry } from "./types-B1W2CPUu.mjs";
3
- import { c as UiNode } from "./types-BAv5qOZX.mjs";
4
- import { t as HeadlessApp } from "./headless-BFI7EXHo.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-D52biu5v.mjs";
6
- import { n as defineSource } from "./define-0af8h-Ro.mjs";
1
+ import { Ir as Snapshot, Un as Position, Y as Api$2, ct as RenderStats, dn as ComponentSchema, gn as FrameDiff, h as Usage, hn as EntitySnapshot, in as Explained, ir as FlowGraph, it as Under, nn as Api$1, or as JournalEntry, t as Api$3, wr as Api } from "./types-BCI9vUA6.mjs";
2
+ import { a as AudioApi, g as EffectsStats, h as EffectsApi, r as UiApi, u as SoundEntry } from "./types-BVSmbgJB.mjs";
3
+ import { c as UiNode } from "./types-k5szXqU1.mjs";
4
+ import { t as HeadlessApp } from "./headless-Bx3WG3fZ.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-B6fvpFoz.mjs";
6
+ import { n as defineSource } from "./define-T-WIPEkg.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-DIOe0nCH.mjs";
1
+ import { a as jsxs, i as jsxDEV, n as JSX, r as jsx, t as Fragment } from "./runtime-c0miURhi.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-DIOe0nCH.mjs";
1
+ import { a as jsxs, n as JSX, r as jsx, t as Fragment } from "./runtime-c0miURhi.mjs";
2
2
  export { Fragment, type JSX, jsx, jsxs };
@@ -1,4 +1,4 @@
1
- import "node:module";
1
+ import { createRequire } from "node:module";
2
2
  //#region \0rolldown/runtime.js
3
3
  var __defProp = Object.defineProperty;
4
4
  var __exportAll = (all, no_symbols) => {
@@ -10,5 +10,6 @@ var __exportAll = (all, no_symbols) => {
10
10
  if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
11
11
  return target;
12
12
  };
13
+ var __require = /* #__PURE__ */ (() => createRequire(import.meta.url))();
13
14
  //#endregion
14
- export { __exportAll as t };
15
+ export { __require as n, __exportAll as t };
@@ -1,4 +1,4 @@
1
- import { _ as UiIntrinsicElements, a as JsxChild, t as DescriptionNode } from "./types-BAv5qOZX.mjs";
1
+ import { _ as UiIntrinsicElements, a as JsxChild, t as DescriptionNode } from "./types-k5szXqU1.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. */
@@ -1,4 +1,4 @@
1
- import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.mjs";
1
+ import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
2
2
  import { r as systemSource, t as memory } from "./memory-CWlqhS7l.mjs";
3
3
  import { a as finishDrafts, i as enableDraftPatches, n as deepFreeze$1, o as openDrafts, r as dropDrafts } from "./drafts-BawpSaVp.mjs";
4
4
  import { _ as pushEntry, c as collectFlows, d as findNode, f as framePath, g as compact, h as slotNames, i as servePaused, l as describeGraph, m as isRestCheckpoint, n as captureFrame, o as epochOf, p as graphHash, r as serveCaptures, s as pageNow$1, t as cancelCaptures } from "./capture-PTJXDpxK.mjs";
@@ -9647,8 +9647,9 @@ function inertHandle() {
9647
9647
  return INERT;
9648
9648
  }
9649
9649
  /**
9650
- * The fields another writer owns on one component of one entity: the fields a running driver
9651
- * holds, and the fields the component type gives to a plugin for good.
9650
+ * The fields another writer owns on one component of one entity: the fields a `mute()` holds and
9651
+ * the `initialOnly` fields of a view's projection (one table, `state.mutes`), and the fields the
9652
+ * component type gives to a plugin for good.
9652
9653
  *
9653
9654
  * @param pctx - Domain context of the projection module.
9654
9655
  * @param entity - The entity to ask about.
@@ -10803,6 +10804,221 @@ function routeHint(hints, projection, key) {
10803
10804
  }
10804
10805
  }
10805
10806
  //#endregion
10807
+ //#region src/plugins/world/projection/mutes.ts
10808
+ /**
10809
+ * Tells a table `mute()` made apart from a shared `initialOnly` seed, which is frozen.
10810
+ *
10811
+ * @param table - A table of `state.mutes`.
10812
+ * @returns True when the table may be written.
10813
+ */
10814
+ function isOwnTable(table) {
10815
+ return !Object.isFrozen(table);
10816
+ }
10817
+ /**
10818
+ * Tells a field set `mute()` made apart from a set of a shared `initialOnly` seed, which is frozen.
10819
+ *
10820
+ * @param fields - A field set of one table.
10821
+ * @returns True when the set may be written.
10822
+ */
10823
+ function isOwnFields(fields) {
10824
+ return !Object.isFrozen(fields);
10825
+ }
10826
+ /**
10827
+ * The table a mute may write: the entity's own one, a copy of the seed it was born with, or a new one.
10828
+ *
10829
+ * @param stored - The table the entity has now, if any.
10830
+ * @returns A writable table.
10831
+ */
10832
+ function ownTable(stored) {
10833
+ if (stored === void 0) return /* @__PURE__ */ new Map();
10834
+ return isOwnTable(stored) ? stored : new Map(stored);
10835
+ }
10836
+ /**
10837
+ * The field set a mute may write: the component's own one, a copy of its seed set, or a new one.
10838
+ *
10839
+ * @param stored - The field set the component has now, if any.
10840
+ * @returns A writable set.
10841
+ */
10842
+ function ownFields(stored) {
10843
+ if (stored === void 0) return /* @__PURE__ */ new Set();
10844
+ return isOwnFields(stored) ? stored : new Set(stored);
10845
+ }
10846
+ /**
10847
+ * The `initialOnly` fields of one component of a view, from the spec of its projection.
10848
+ *
10849
+ * @param state - The projection branch of the plugin state.
10850
+ * @param entity - The entity of the view.
10851
+ * @param name - The component name.
10852
+ * @returns The seed set, or `undefined` for an entity that is no view of such a projection.
10853
+ */
10854
+ function initialFieldsOf(state, entity, name) {
10855
+ const projection = state.byEntity.get(entity)?.projection;
10856
+ const spec = projection === void 0 ? void 0 : state.specs.get(projection);
10857
+ return spec === void 0 ? void 0 : state.initialOnly.get(spec)?.get(name);
10858
+ }
10859
+ /**
10860
+ * Deletes a released field set once it is empty, and the entity's table once no component is
10861
+ * left. Only the table and the set this mute filled are touched, so a remover that runs after a
10862
+ * clear or a new birth on the same id never drops a newer mute.
10863
+ *
10864
+ * @param mutes - The mute tables of every entity.
10865
+ * @param entity - The muted entity.
10866
+ * @param table - The table the mute wrote.
10867
+ * @param name - The muted component's name.
10868
+ * @param owned - The field set the remover released from.
10869
+ */
10870
+ function dropEmptyMute(mutes, entity, table, name, owned) {
10871
+ if (owned.size > 0 || mutes.get(entity) !== table || table.get(name) !== owned) return;
10872
+ table.delete(name);
10873
+ if (table.size === 0) mutes.delete(entity);
10874
+ }
10875
+ /**
10876
+ * Hands fields of one component of one entity to another writer, until the remover runs. A view
10877
+ * born with an `initialOnly` seed gets its own copy first. The remover keeps the seed fields, asked
10878
+ * when it runs: a mute made inside the spawn came before the view was known.
10879
+ *
10880
+ * @param state - The projection branch of the plugin state.
10881
+ * @param entity - The entity.
10882
+ * @param name - The component name.
10883
+ * @param fields - The field names the caller owns.
10884
+ * @returns The remover; a no-op when called twice.
10885
+ */
10886
+ function muteFields(state, entity, name, fields) {
10887
+ const table = ownTable(state.mutes.get(entity));
10888
+ const owned = ownFields(table.get(name));
10889
+ for (const field of fields) owned.add(field);
10890
+ forgetJoined(state, owned);
10891
+ table.set(name, owned);
10892
+ state.mutes.set(entity, table);
10893
+ let released = false;
10894
+ return () => {
10895
+ if (released) return;
10896
+ released = true;
10897
+ const kept = initialFieldsOf(state, entity, name);
10898
+ for (const field of fields) if (kept?.has(field) !== true) owned.delete(field);
10899
+ forgetJoined(state, owned);
10900
+ dropEmptyMute(state.mutes, entity, table, name, owned);
10901
+ };
10902
+ }
10903
+ /**
10904
+ * Builds the frozen seed of a projection's `initialOnly` list: component name to its fields, a
10905
+ * component named twice with both lists joined.
10906
+ *
10907
+ * @param spec - The projection spec.
10908
+ * @param pairs - Its `initialOnly` list, not empty.
10909
+ * @returns The seed.
10910
+ * @throws {Error} For a pair with no field.
10911
+ */
10912
+ function buildSeed(spec, pairs) {
10913
+ const seed = /* @__PURE__ */ new Map();
10914
+ for (const [component, fields] of pairs) {
10915
+ const name = component.componentName;
10916
+ if (fields.length === 0) throw new Error(`[game] Projection "${spec.name}" lists ${name} in initialOnly with no field.\n Name the fields only the birth of a view writes, or drop the pair.`);
10917
+ seed.set(name, Object.freeze(/* @__PURE__ */ new Set([...seed.get(name) ?? [], ...fields])));
10918
+ }
10919
+ return Object.freeze(seed);
10920
+ }
10921
+ /**
10922
+ * Checks the `initialOnly` list of a spec and keeps its seed: once per spec, since a name is
10923
+ * registered once and `replace` brings a new spec. A spec without the option, or with an empty
10924
+ * list, has none.
10925
+ *
10926
+ * @param state - The projection branch of the plugin state.
10927
+ * @param spec - The spec `register` or `replace` stores.
10928
+ * @returns The seed, or `undefined`.
10929
+ * @throws {Error} For a pair with no field; nothing is kept then.
10930
+ */
10931
+ function learnSeed(state, spec) {
10932
+ const pairs = spec.initialOnly;
10933
+ if (pairs === void 0 || pairs.length === 0) return void 0;
10934
+ const seed = buildSeed(spec, pairs);
10935
+ state.initialOnly.set(spec, seed);
10936
+ return seed;
10937
+ }
10938
+ /**
10939
+ * Joins a seed into a table of the entity's own, in place, so the remover of every mute that wrote
10940
+ * the table still holds its table and its sets: a component the table lacks gets the shared set
10941
+ * of the seed, the set a mute wrote gets the fields of the seed.
10942
+ *
10943
+ * @param state - The projection branch of the plugin state.
10944
+ * @param table - The entity's own table.
10945
+ * @param seed - The seed to join.
10946
+ */
10947
+ function joinSeed(state, table, seed) {
10948
+ for (const [name, fields] of seed) {
10949
+ const stored = table.get(name);
10950
+ if (stored === void 0) {
10951
+ table.set(name, fields);
10952
+ continue;
10953
+ }
10954
+ const owned = ownFields(stored);
10955
+ for (const field of fields) owned.add(field);
10956
+ forgetJoined(state, owned);
10957
+ table.set(name, owned);
10958
+ }
10959
+ }
10960
+ /**
10961
+ * Gives a view that was just born the seed of its projection, so from now on nothing of the
10962
+ * projection writes or compares those fields. The birth itself wrote them from `view`. A view a
10963
+ * listener of its spawn muted already keeps its table, and the seed joins it.
10964
+ *
10965
+ * @param state - The projection branch of the plugin state.
10966
+ * @param spec - The projection spec.
10967
+ * @param entity - The entity of the new view.
10968
+ */
10969
+ function seedMutes(state, spec, entity) {
10970
+ if (spec.initialOnly === void 0) return;
10971
+ const seed = state.initialOnly.get(spec);
10972
+ if (seed === void 0) return;
10973
+ const stored = state.mutes.get(entity);
10974
+ if (stored === void 0) {
10975
+ state.mutes.set(entity, seed);
10976
+ return;
10977
+ }
10978
+ const table = ownTable(stored);
10979
+ joinSeed(state, table, seed);
10980
+ state.mutes.set(entity, table);
10981
+ }
10982
+ /**
10983
+ * Moves a view with a table of its own from one seed to the next: a set of the old seed goes, the
10984
+ * new seed joins. A set a mute wrote keeps every field it holds, an old seed's field it copied too,
10985
+ * since the table does not say which mute named it. A table left empty goes.
10986
+ *
10987
+ * @param state - The projection branch of the plugin state.
10988
+ * @param entity - The entity of the view.
10989
+ * @param stored - The table the view has now, if any.
10990
+ * @param from - The seed of the old spec, if any.
10991
+ * @param to - The seed of the new spec, if any.
10992
+ */
10993
+ function reseedOwn(state, entity, stored, from, to) {
10994
+ const table = ownTable(stored);
10995
+ for (const [name, fields] of from ?? []) if (table.get(name) === fields) table.delete(name);
10996
+ if (to !== void 0) joinSeed(state, table, to);
10997
+ if (table.size === 0) state.mutes.delete(entity);
10998
+ else state.mutes.set(entity, table);
10999
+ }
11000
+ /**
11001
+ * Moves the views of a replaced projection from the seed of the old spec to the seed of the new
11002
+ * one. A view that holds the old seed, or none when the old spec had none, takes the new seed. A
11003
+ * view a `mute()` gave its own table keeps it: the sets of the old seed in it go, the new seed
11004
+ * joins it.
11005
+ *
11006
+ * @param state - The projection branch of the plugin state.
11007
+ * @param name - The projection name.
11008
+ * @param from - The seed of the old spec, if any.
11009
+ * @param to - The seed of the new spec, if any.
11010
+ */
11011
+ function reseedViews(state, name, from, to) {
11012
+ if (from === to) return;
11013
+ for (const view of state.byEntity.values()) {
11014
+ if (view.projection !== name) continue;
11015
+ const stored = state.mutes.get(view.entity);
11016
+ if (stored !== from) reseedOwn(state, view.entity, stored, from, to);
11017
+ else if (to === void 0) state.mutes.delete(view.entity);
11018
+ else state.mutes.set(view.entity, to);
11019
+ }
11020
+ }
11021
+ //#endregion
10806
11022
  //#region src/plugins/world/projection/reconcile.ts
10807
11023
  /**
10808
11024
  * Creates the empty set of used hints. It lives in its own non-exported function because lint
@@ -10894,6 +11110,7 @@ function enterEntry(pctx, spec, mounted, entry) {
10894
11110
  const view = createViewRecord(entity, spec.name, entry.key, entry.item, values, entry.direct ? "mount" : "change");
10895
11111
  const state = pctx.ctx.state.projection;
10896
11112
  const building = state.building;
11113
+ seedMutes(state, spec, entity);
10897
11114
  mounted.live.set(entry.key, view);
10898
11115
  state.byEntity.set(entity, view);
10899
11116
  state.membershipVersion += 1;
@@ -11739,39 +11956,6 @@ function isConvergeCause(cause) {
11739
11956
  return cause === "load" || cause === "restore";
11740
11957
  }
11741
11958
  /**
11742
- * Creates the empty mute table of one entity. It lives in its own non-exported function because
11743
- * lint rule L5 refuses a collection built inside an exported declaration.
11744
- *
11745
- * @returns An empty table of component name to owned fields.
11746
- */
11747
- function emptyMuteTable() {
11748
- return /* @__PURE__ */ new Map();
11749
- }
11750
- /**
11751
- * Creates the empty field set of one muted component.
11752
- *
11753
- * @returns An empty set of field names.
11754
- */
11755
- function emptyFieldSet() {
11756
- return /* @__PURE__ */ new Set();
11757
- }
11758
- /**
11759
- * Deletes a released field set once it is empty, and the entity's table once no component is
11760
- * left. Only the set and table still stored are touched, so a remover that runs after a clear
11761
- * never drops a newer mute.
11762
- *
11763
- * @param mutes - The mute tables of every entity.
11764
- * @param entity - The muted entity.
11765
- * @param name - The muted component's name.
11766
- * @param owned - The field set the remover released from.
11767
- */
11768
- function dropEmptyMute(mutes, entity, name, owned) {
11769
- const byComponent = mutes.get(entity);
11770
- if (owned.size > 0 || byComponent?.get(name) !== owned) return;
11771
- byComponent.delete(name);
11772
- if (byComponent.size === 0) mutes.delete(entity);
11773
- }
11774
- /**
11775
11959
  * Creates the empty dirty record the next reconcile reads.
11776
11960
  *
11777
11961
  * @returns Nothing to reconcile yet.
@@ -11876,13 +12060,18 @@ function createProjectionApi(ctx, deps) {
11876
12060
  return {
11877
12061
  register: (spec) => {
11878
12062
  if (state.specs.has(spec.name)) throw new Error(`[game] Projection "${spec.name}" is registered twice.\n Give the second projection another name.`);
12063
+ learnSeed(state, spec);
11879
12064
  state.specs.set(spec.name, spec);
11880
12065
  },
11881
12066
  replace: (spec) => {
11882
- if (!state.specs.has(spec.name)) throw new Error(`[game] Projection "${spec.name}" is not registered.\n Register it before replacing it.`);
12067
+ const previous = state.specs.get(spec.name);
12068
+ if (previous === void 0) throw new Error(`[game] Projection "${spec.name}" is not registered.\n Register it before replacing it.`);
11883
12069
  const mounted = state.mounted.has(spec.name);
11884
12070
  if (mounted) checkLayers(spec, state.layers);
12071
+ const from = state.initialOnly.get(previous);
12072
+ const seed = learnSeed(state, spec);
11885
12073
  state.specs.set(spec.name, spec);
12074
+ reseedViews(state, spec.name, from, seed);
11886
12075
  if (mounted) forceRerun();
11887
12076
  },
11888
12077
  setLayers: (list) => {
@@ -11915,22 +12104,7 @@ function createProjectionApi(ctx, deps) {
11915
12104
  playSettle(pctx, view, spec, restingPeers(mounted), looseComponents(pctx, view));
11916
12105
  dropIfStill(pctx, view);
11917
12106
  },
11918
- mute: (entity, component, fields) => {
11919
- const byComponent = state.mutes.get(entity) ?? emptyMuteTable();
11920
- const owned = byComponent.get(component.componentName) ?? emptyFieldSet();
11921
- for (const field of fields) owned.add(field);
11922
- forgetJoined(state, owned);
11923
- byComponent.set(component.componentName, owned);
11924
- state.mutes.set(entity, byComponent);
11925
- let released = false;
11926
- return () => {
11927
- if (released) return;
11928
- released = true;
11929
- for (const field of fields) owned.delete(field);
11930
- forgetJoined(state, owned);
11931
- dropEmptyMute(state.mutes, entity, component.componentName, owned);
11932
- };
11933
- },
12107
+ mute: (entity, component, fields) => muteFields(state, entity, component.componentName, fields),
11934
12108
  lift: (entity, on) => {
11935
12109
  const view = state.byEntity.get(entity);
11936
12110
  if (view === void 0) return;
@@ -12380,6 +12554,7 @@ function createProjectionState() {
12380
12554
  keys: emptyMap$9(),
12381
12555
  keysByEntity: emptyMap$9(),
12382
12556
  mutes: emptyMap$9(),
12557
+ initialOnly: emptyWeakMap$2(),
12383
12558
  ownedSets: emptyWeakMap$2(),
12384
12559
  joinedMutes: emptyWeakMap$2(),
12385
12560
  converged: [],
@@ -64225,9 +64400,11 @@ function scenesFor() {
64225
64400
  /**
64226
64401
  * Types a projection: keyed items of the model turned into entities. `Item` is inferred from the
64227
64402
  * return of `from` and reaches `key`, `view` and every motion hook; `layer` and `lift` stay
64228
- * literal, so `defineScene` can check them against the layers of the scene.
64403
+ * literal, so `defineScene` can check them against the layers of the scene. Each pair of
64404
+ * `initialOnly` has its field names checked against its own component.
64229
64405
  *
64230
- * @param spec - Name, layer, optional lift layer, `from`, `key`, `view` and the motion hooks.
64406
+ * @param spec - Name, layer, optional lift layer, `from`, `key`, `view`, the motion hooks and
64407
+ * the `initialOnly` fields.
64231
64408
  * @returns The same spec, typed.
64232
64409
  * @example
64233
64410
  * ```ts
@@ -1,7 +1,7 @@
1
- import { $n as FeaturePlugin, Dr as Json, dr as Descriptor, gr as NodeFx, hr as Hint, sr as NodeTable, tr as AnyFlow, xr as FakeClock, yr as ClockSource } from "./types-K3qfyTu0.mjs";
2
- import { t as createApp } from "./index-Cs4qaPMq.mjs";
3
- import { b as saveOf, v as WithGameState, y as memory } from "./types-Dh2cyp0H.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-BFI7EXHo.mjs";
1
+ import { $n as FeaturePlugin, Dr as Json, dr as Descriptor, gr as NodeFx, hr as Hint, sr as NodeTable, tr as AnyFlow, xr as FakeClock, yr as ClockSource } from "./types-BCI9vUA6.mjs";
2
+ import { t as createApp } from "./index-BMpWPXvo.mjs";
3
+ import { b as saveOf, v as WithGameState, y as memory } from "./types-B4G8sOED.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-Bx3WG3fZ.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 { en as refuseStart, in as type, m as flattenFeatures, t as createApp, tn as exit } from "./src-C6XBMo4Q.mjs";
1
+ import { en as refuseStart, in as type, m as flattenFeatures, t as createApp, tn as exit } from "./src-ChniuNDc.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-Bxxl_mQX.mjs";
@@ -1,7 +1,7 @@
1
- import { $ as PixiModule, $n as FeaturePlugin, Dr as Json, Lr as SnapshotOf, Mr as PlayerStateProvider, Nr as ProviderCall, Pr as SaveDoc, Tr as Config, X as Config$2, a as Config$3, d as Manifest, lt as Orientation, n as AssetsIo, tr as AnyFlow, ur as TypeTag, xr as FakeClock, yr as ClockSource, zn as Config$1 } from "./types-K3qfyTu0.mjs";
2
- import { o as AudioContextLike, s as Config$4 } from "./types-B1W2CPUu.mjs";
3
- import { R as I18nApi, U as StringTable, W as TextKey } from "./types-BAv5qOZX.mjs";
4
- import { St as effectsPlugin, Tt as audioPlugin, ht as PlatformProvider, i as screen, pt as platformPlugin, t as createApp } from "./index-Cs4qaPMq.mjs";
1
+ import { $ as PixiModule, $n as FeaturePlugin, Dr as Json, Lr as SnapshotOf, Mr as PlayerStateProvider, Nr as ProviderCall, Pr as SaveDoc, Tr as Config, X as Config$2, a as Config$3, d as Manifest, lt as Orientation, n as AssetsIo, tr as AnyFlow, ur as TypeTag, xr as FakeClock, yr as ClockSource, zn as Config$1 } from "./types-BCI9vUA6.mjs";
2
+ import { o as AudioContextLike, s as Config$4 } from "./types-BVSmbgJB.mjs";
3
+ import { R as I18nApi, U as StringTable, W as TextKey } from "./types-k5szXqU1.mjs";
4
+ import { St as effectsPlugin, Tt as audioPlugin, ht as PlatformProvider, i as screen, pt as platformPlugin, t as createApp } from "./index-BMpWPXvo.mjs";
5
5
  import { AnyPluginInstance } from "@moku-labs/core";
6
6
 
7
7
  //#region src/plugins/model/store/providers/memory.d.ts
@@ -1,5 +1,5 @@
1
- import { Dr as Json, Ir as Snapshot } from "./types-K3qfyTu0.mjs";
2
- import { t as HeadlessApp } from "./headless-BFI7EXHo.mjs";
1
+ import { Dr as Json, Ir as Snapshot } from "./types-BCI9vUA6.mjs";
2
+ import { t as HeadlessApp } from "./headless-Bx3WG3fZ.mjs";
3
3
  import { Log } from "@moku-labs/common/browser";
4
4
 
5
5
  //#region src/plugins/flow/doors/types.d.ts
@@ -4273,9 +4273,35 @@ type AnyProjectionMotion = {
4273
4273
  readonly change?: ChangeHooks<never>;
4274
4274
  settle?(view: ViewHandle<unknown>, components: readonly string[]): Motion;
4275
4275
  };
4276
+ /**
4277
+ * One pair of `ProjectionSpec.initialOnly`: a component and the fields of it that `view` gives a
4278
+ * view once, when it is born. The field names are checked against the component's own value.
4279
+ *
4280
+ * @example
4281
+ * ```ts
4282
+ * const arc: InitialOnlyPair<ShapeValue> = [Shape, ["sweep"]];
4283
+ * ```
4284
+ */
4285
+ type InitialOnlyPair<Value extends object> = readonly [ComponentHandle<Value>, readonly (keyof Value & string)[]];
4286
+ /**
4287
+ * The `initialOnly` list of a projection: one pair for each value type of `Values`, each pair
4288
+ * checked against its own component. `projection()` infers `Values` from the list, so
4289
+ * `[[Shape, ["swep"]]]` is a type error.
4290
+ *
4291
+ * @example
4292
+ * ```ts
4293
+ * const fields: InitialOnly<[ShapeValue, TransformValue]> = [
4294
+ * [Shape, ["sweep", "alpha"]],
4295
+ * [Transform, ["rotation"]]
4296
+ * ];
4297
+ * ```
4298
+ */
4299
+ type InitialOnly<Values extends readonly object[]> = { readonly [Index in keyof Values]: InitialOnlyPair<Values[Index]> };
4276
4300
  /**
4277
4301
  * One projection: keyed items of the model turned into entities. `Item` is inferred from the
4278
4302
  * return of `from`; `layer` and `lift` keep their literal types so a scene can check them.
4303
+ * `Values` are the value types of the `initialOnly` pairs, inferred by `projection()`; an
4304
+ * annotation that leaves it out accepts any field name.
4279
4305
  *
4280
4306
  * @example
4281
4307
  * ```ts
@@ -4289,7 +4315,7 @@ type AnyProjectionMotion = {
4289
4315
  * };
4290
4316
  * ```
4291
4317
  */
4292
- type ProjectionSpec<Item, LayerName extends string, LiftName extends string, Player, Session> = {
4318
+ type ProjectionSpec<Item, LayerName extends string, LiftName extends string, Player, Session, Values extends readonly object[] = readonly Record<string, unknown>[]> = {
4293
4319
  readonly name: string;
4294
4320
  readonly layer: LayerName;
4295
4321
  readonly lift?: LiftName;
@@ -4297,6 +4323,35 @@ type ProjectionSpec<Item, LayerName extends string, LiftName extends string, Pla
4297
4323
  key?(item: Item): string;
4298
4324
  view(item: Item): ViewOutput;
4299
4325
  readonly motion?: ProjectionMotion<Item>;
4326
+ /**
4327
+ * Fields another writer owns once a view is born. `view` gives them their first value when the
4328
+ * view spawns; from then on nothing of the projection writes or compares them: not a changed
4329
+ * item, not a motion or its finish, not the check at the end of a motion (no
4330
+ * `world:view-corrected`), not a rollback, `settle(entity)`, a restore or a load. These are the
4331
+ * rules of `mute()`, for every view of the projection and for its whole life. A `mute()` on the
4332
+ * view adds to them, and its release keeps them. Left out, the projection writes every field.
4333
+ *
4334
+ * @example
4335
+ * ```ts
4336
+ * // The timer ring of a chest: born full, then the system `board.rings` draws its arc from `Now`.
4337
+ * export const marks = projection({
4338
+ * name: "board.marks",
4339
+ * layer: "marks",
4340
+ * from: (player: Player) => player.board.timers,
4341
+ * key: timer => timer.id,
4342
+ * view: timer => [Shape({ kind: "arc", w: 28, h: 28, strokeWidth: 2.2, sweep: 1 })],
4343
+ * motion: {
4344
+ * enter: view => {
4345
+ * view.set(Shape, { alpha: 0 });
4346
+ * return view.toRest(Shape, { ms: 200 });
4347
+ * }
4348
+ * },
4349
+ * initialOnly: [[Shape, ["sweep"]]]
4350
+ * });
4351
+ * // The fade ends with the 0.42 the system wrote: no full ring, no `world:view-corrected`.
4352
+ * ```
4353
+ */
4354
+ readonly initialOnly?: InitialOnly<Values>;
4300
4355
  };
4301
4356
  /**
4302
4357
  * A projection spec with its item and layer types erased, as the world stores it.
@@ -4319,7 +4374,8 @@ type AnyProjectionSpec = {
4319
4374
  from(player: Json, session: Json): unknown;
4320
4375
  key?(item: unknown): string;
4321
4376
  view(item: unknown): ViewOutput;
4322
- readonly motion?: AnyProjectionMotion;
4377
+ readonly motion?: AnyProjectionMotion; /** The `initialOnly` pairs, their field names no longer tied to the component. */
4378
+ readonly initialOnly?: readonly (readonly [ComponentHandle<object>, readonly string[]])[];
4323
4379
  };
4324
4380
  /**
4325
4381
  * Why a reconcile runs. Merged over the frame; the cause table decides play or direct. A
@@ -4442,6 +4498,12 @@ type Dirty = {
4442
4498
  roots: Set<Root>;
4443
4499
  force: boolean;
4444
4500
  };
4501
+ /**
4502
+ * Component name to the fields another writer owns, of one entity. A frozen table, and a frozen
4503
+ * set in one, is the `initialOnly` seed every view of one projection shares: nothing writes into
4504
+ * it, and `mute()` copies it before it adds a field.
4505
+ */
4506
+ type MuteTable = ReadonlyMap<string, ReadonlySet<string>>;
4445
4507
  /**
4446
4508
  * A mute's fields joined with a type's owned fields, and the owned set they were joined with.
4447
4509
  */
@@ -4471,8 +4533,14 @@ type ProjectionState = {
4471
4533
  * The reverse of `keys`, so `keyOf` answers for a registered element too. The entry of an
4472
4534
  * entity that is gone is dropped with its rest pose, and its side of `keys` with it.
4473
4535
  */
4474
- keysByEntity: Map<Entity, ProjectionKey>; /** Entity to component name to the fields another writer owns. */
4475
- mutes: Map<Entity, Map<string, Set<string>>>; /** The owned fields of each component type as a set, by the type's frozen `owned` list: made once. */
4536
+ keysByEntity: Map<Entity, ProjectionKey>;
4537
+ /**
4538
+ * Entity to component name to the fields another writer owns: what `mute()` handed over, and
4539
+ * the shared `initialOnly` seed a view of such a projection is born with. A view a listener of
4540
+ * its spawn muted keeps that table, and the seed joins it.
4541
+ */
4542
+ mutes: Map<Entity, MuteTable>; /** The `initialOnly` seed of each registered spec that has one, frozen, built at `register` and `replace`. */
4543
+ initialOnly: WeakMap<AnyProjectionSpec, MuteTable>; /** The owned fields of each component type as a set, by the type's frozen `owned` list: made once. */
4476
4544
  ownedSets: WeakMap<readonly string[], ReadonlySet<string>>; /** The muted and the owned fields joined, by the mute's field set: dropped when `mute()` or its release changes it. */
4477
4545
  joinedMutes: WeakMap<ReadonlySet<string>, JoinedFields>; /** The `onConverged` listeners: the owners of elements, told after a restore or a load. */
4478
4546
  converged: Array<() => void>;
@@ -4646,7 +4714,9 @@ type ProjectionApi = {
4646
4714
  */
4647
4715
  settle(entity: Entity): void;
4648
4716
  /**
4649
- * Hands a set of fields to another writer. Tracks never write them, also not on `finish()`.
4717
+ * Hands a set of fields to another writer. Tracks never write them, also not on `finish()`. On
4718
+ * a view whose projection names `initialOnly` fields the mute adds to them, and the remover keeps
4719
+ * them.
4650
4720
  *
4651
4721
  * @param entity - The entity of the view.
4652
4722
  * @param component - The component whose fields are taken over.
@@ -6421,7 +6491,7 @@ type SystemTiming = {
6421
6491
  ms: Float64Array;
6422
6492
  };
6423
6493
  declare namespace types_d_exports$3 {
6424
- export { AnyComponentType, AnyComponentValue, AnyProjectionSpec, AnySystem, Api$2 as Api, Cause, ChangeHook, ComponentHandle, ComponentSchema, ComponentType, ComponentValue, Config$3 as Config, Deps$3 as Deps, DescriptionNode, Ease, EcsApi, EcsModule, Entity, EntityDiff, EntitySnapshot, Events$3 as Events, Explained, FrameDiff, GameSystemDefinition, KernelSlice$3 as KernelSlice, LayerSort, LayerSpec, ModelCommitted, Motion, MotionCause, MotionHandle, Mut, Narrowed, NumericFields, Owner, ProjectionApi, ProjectionKey, ProjectionModule, ProjectionMotion, ProjectionSpec, QueryTerm, QueryTuple, ReducedMotion, ResourceType, RestOptions, State$3 as State, SystemContext, SystemContextOf, SystemDefinition, SystemFor, SystemTiming, TagType, TrackOptions, TrackSegment, TweenDriver, TweenOptions, ViewHandle, ViewOutput, WorldCtx, WorldMode, WorldPhase, WorldSnapshot };
6494
+ export { AnyComponentType, AnyComponentValue, AnyProjectionSpec, AnySystem, Api$2 as Api, Cause, ChangeHook, ComponentHandle, ComponentSchema, ComponentType, ComponentValue, Config$3 as Config, Deps$3 as Deps, DescriptionNode, Ease, EcsApi, EcsModule, Entity, EntityDiff, EntitySnapshot, Events$3 as Events, Explained, FrameDiff, GameSystemDefinition, InitialOnly, InitialOnlyPair, KernelSlice$3 as KernelSlice, LayerSort, LayerSpec, ModelCommitted, Motion, MotionCause, MotionHandle, Mut, Narrowed, NumericFields, Owner, ProjectionApi, ProjectionKey, ProjectionModule, ProjectionMotion, ProjectionSpec, QueryTerm, QueryTuple, ReducedMotion, ResourceType, RestOptions, State$3 as State, SystemContext, SystemContextOf, SystemDefinition, SystemFor, SystemTiming, TagType, TrackOptions, TrackSegment, TweenDriver, TweenOptions, ViewHandle, ViewOutput, WorldCtx, WorldMode, WorldPhase, WorldSnapshot };
6425
6495
  }
6426
6496
  /**
6427
6497
  * world plugin events.
@@ -1,5 +1,5 @@
1
- import { $ as PixiModule, A as SyncApi, An as NumericFields, Dr as Json, En as Ease, Er as Events$3, Fn as TrackSegment, Ln as Api$2, Nn as ReducedMotion, O as FilterSlot, Pn as TrackOptions, Q as PixiFilter, Ur as Events$5, Y as Api$4, b as Events$4, dr as Descriptor, et as PixiSprite, fn as ComponentType, ft as FilterCache, k as FilterSlotInputs, kn as MotionHandle, ln as AnyComponentValue, mn as Entity, ni as Events$2, nn as Api$3, qr as Api$1, ri as Require, s as Events$1, sn as AnyComponent, t as Api$5, tt as PixiTexture, un as ComponentHandle, ur as TypeTag, ut as Point, wr as Api$6 } from "./types-K3qfyTu0.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-BAv5qOZX.mjs";
1
+ import { $ as PixiModule, A as SyncApi, An as NumericFields, Dr as Json, En as Ease, Er as Events$3, Fn as TrackSegment, Ln as Api$2, Nn as ReducedMotion, O as FilterSlot, Pn as TrackOptions, Q as PixiFilter, Ur as Events$5, Y as Api$4, b as Events$4, dr as Descriptor, et as PixiSprite, fn as ComponentType, ft as FilterCache, k as FilterSlotInputs, kn as MotionHandle, ln as AnyComponentValue, mn as Entity, ni as Events$2, nn as Api$3, qr as Api$1, ri as Require, s as Events$1, sn as AnyComponent, t as Api$5, tt as PixiTexture, un as ComponentHandle, ur as TypeTag, ut as Point, wr as Api$6 } from "./types-BCI9vUA6.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-k5szXqU1.mjs";
3
3
  import { Log } from "@moku-labs/common/browser";
4
4
  import { PluginCtx } from "@moku-labs/core";
5
5
 
@@ -1,4 +1,4 @@
1
- import { An as NumericFields, Cn as TagType, Dn as Motion, Dr as Json, En as Ease, In as ViewHandle, K as TransformValue, Ln as Api$1, Nn as ReducedMotion, On as MotionCause, Y as Api$3, _r as Answer, cn as AnyComponentType, dr as Descriptor, dt as ViewportSize, fn as ComponentType, hr as Hint, jn as ProjectionMotion, kn as MotionHandle, ln as AnyComponentValue, mn as Entity, nn as Api$2, qr as Api, ri as Require, s as Events$1, sn as AnyComponent, t as Api$4, vr as Api$5, wn as ChangeHook } from "./types-K3qfyTu0.mjs";
1
+ import { An as NumericFields, Cn as TagType, Dn as Motion, Dr as Json, En as Ease, In as ViewHandle, K as TransformValue, Ln as Api$1, Nn as ReducedMotion, On as MotionCause, Y as Api$3, _r as Answer, cn as AnyComponentType, dr as Descriptor, dt as ViewportSize, fn as ComponentType, hr as Hint, jn as ProjectionMotion, kn as MotionHandle, ln as AnyComponentValue, mn as Entity, nn as Api$2, qr as Api, ri as Require, s as Events$1, sn as AnyComponent, t as Api$4, vr as Api$5, wn as ChangeHook } from "./types-BCI9vUA6.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";
@@ -1,9 +1,9 @@
1
- import { Vr as Api$3, Y as Api, nn as Api$1, vr as Api$4, wr as Api$2 } from "./types-K3qfyTu0.mjs";
2
- import { P as AnimApi, r as UiApi } from "./types-B1W2CPUu.mjs";
3
- import { N as InputApi } from "./types-BAv5qOZX.mjs";
4
- import { r as Repro } from "./headless-BFI7EXHo.mjs";
5
- import { a as InputOf, r as ControlApp } from "./types-D52biu5v.mjs";
6
- import { t as commands } from "./commands-BGrtxBga.mjs";
1
+ import { Vr as Api$3, Y as Api, nn as Api$1, vr as Api$4, wr as Api$2 } from "./types-BCI9vUA6.mjs";
2
+ import { P as AnimApi, r as UiApi } from "./types-BVSmbgJB.mjs";
3
+ import { N as InputApi } from "./types-k5szXqU1.mjs";
4
+ import { r as Repro } from "./headless-Bx3WG3fZ.mjs";
5
+ import { a as InputOf, r as ControlApp } from "./types-B6fvpFoz.mjs";
6
+ import { t as commands } from "./commands-BZPrVtJT.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-DMx0vv_3.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-D0cotXHi.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
@@ -532,6 +532,7 @@ The graph. Modules `runner`, `gate`, `inbox`, `fx`, `features`. Runner methods s
532
532
  - When a system runs: before each run the world checks it. A system with a `query` is skipped while a term of its query has no entity (the smallest store among the terms is empty): no walk, no `mut()` mark, no timing. A system without a query always runs. `system({ ..., scenes: ["board"] })` runs only while one of those scenes is mounted or leaving: `scenes` calls `app.world.ecs.setScene(id)` at every switch, and the scene before leaves until nothing carries `Exiting` (the elements of its JSX views played their exit; the next scene's entities already stand then, so a `scenes` system writes only its own scene's entities). A dev build throws at start for a name in `scenes` no feature declares: `[game] System "board.idle" runs on the scene "bord", which no feature declares.` `ctx.resumed` is true on the first run after a skip (a cache or a remembered cue starts over then). The same for every system, the engine's included; 0 B a frame. A run with no rows does not happen any more: work a system did besides its rows (a hover, a drop or a press that ends, a resource reset, something that outlives its entities) goes to a system with `query: []` and `scenes`, reading its rows with `world.query()`. From 0.15.3: delete `systemsRun` from every feature (the type refuses it), rewrite the systems that work outside their rows, add `scenes` only to a system whose entities stand on every screen; `ecs.hold` and `ecs.isActive` are gone (a test asks `app.scenes.current()` or whether the system ran). World README, "When a system runs".
533
533
  - Motion hooks are told why they play: `enter(view, item, hint, cause)` and `exit(view, item, hint, cause)` get `World.MotionCause`, `"mount"` (the view comes or goes with its screen: a mount, an unmount, a load, a restore, a paused or fast world) or `"change"` (a commit). A world projection plays them only for `"change"`; `ui` plays them for both. `app.world.projection.causeOf(entity)` answers how a view came or how it is leaving, also in a removal hook of its despawn, until the next frame.
534
534
  - `app.world.projection.replace(spec)` swaps the spec of a registered projection; a mounted one runs its new `view` on the next frame. An unknown name throws. The caller is the dev hot swap.
535
+ - `projection({ …, initialOnly: [[Shape, ["sweep"]]] })`: `view` gives those fields once, at the birth of a view; after that they belong to another writer (a system drawing a timer arc from `Now`), and no changed item, motion, end-of-motion check (`world:view-corrected`), rollback, `settle`, restore or load writes or compares them, as with `mute()` for every view's whole life. Field names are checked per component; a pair with no field throws at register. Absent, every field is the projection's.
535
536
  - `input`: one followed pointer. A finger that has not started a gesture (pressed, inside the tap slop, no long press, no trace) gives way to the next finger that goes down, wherever it rests, and its press is cancelled; a finger that started a gesture keeps it. `Pointer.id` is the followed `pointerId` (`-1` at rest): a system that measures the finger's travel starts over when it changes.
536
537
  - `Draggable({ payload, carry?, aim? })`: `aim: { x, y }`, a point of the view in its own units, moves the hover and the drop lookup from the finger to that point of the view in the hand; `null` (default) is the finger.
537
538
  - `pluginConfigs.renderer.onDemand: true` draws a frame only when something visible changed (a written view, a filter value, a resize, a wake, a capture); `app.renderer.stats().drawn` is the frames drawn per second (`fps` without it); a game that writes into its own `Display` object calls `app.renderer.invalidate(entity)` before the write; `renderer.sync.debug.verifyFrames(true)` (dev/debug) checks skipped frames by pixels and logs `renderer:missed-frame`; a dev build warns `renderer:missed-mark` for a write without the call.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moku-labs/game",
3
- "version": "0.15.35",
3
+ "version": "0.15.37",
4
4
  "description": "2D puzzle game engine on TypeScript and PixiJS, built on @moku-labs/core.",
5
5
  "type": "module",
6
6
  "sideEffects": [