@moku-labs/game 0.9.0 → 0.10.0

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 (53) hide show
  1. package/README.md +81 -22
  2. package/bin/moku-game.mjs +4 -0
  3. package/dist/app/page.d.mts +41 -0
  4. package/dist/app/page.mjs +376 -0
  5. package/dist/app/system.d.mts +129 -0
  6. package/dist/app/system.mjs +307 -0
  7. package/dist/app.d.mts +37 -0
  8. package/dist/app.mjs +235 -0
  9. package/dist/assets-BHwTLVta.mjs +7391 -0
  10. package/dist/assets.d.mts +1 -1
  11. package/dist/assets.mjs +1 -7390
  12. package/dist/cli.d.mts +70 -0
  13. package/dist/cli.mjs +1650 -0
  14. package/dist/{commands-DuwCxK5t.d.mts → commands-C4QlqijJ.d.mts} +5 -5
  15. package/dist/config-CdARrrhU.mjs +81 -0
  16. package/dist/control.d.mts +11 -10
  17. package/dist/control.mjs +3 -3
  18. package/dist/{define-B6pHpdBi.d.mts → define-CCc0ozKe.d.mts} +2 -2
  19. package/dist/{dev-wKLgOw7c.mjs → dev-Cc50Dk7H.mjs} +1 -1
  20. package/dist/drafts-BawpSaVp.mjs +156 -0
  21. package/dist/fake-MpzwZhIZ.mjs +87 -0
  22. package/dist/{headless-SCQXJxQf.d.mts → headless-G4nuZ-xz.d.mts} +1 -1
  23. package/dist/hot.d.mts +4 -6
  24. package/dist/hot.mjs +8 -9
  25. package/dist/{index-BO9kZzY3.d.mts → index-xxSxKJJW.d.mts} +17 -17
  26. package/dist/index.d.mts +5 -5
  27. package/dist/index.mjs +1 -1
  28. package/dist/inspect-la_KkjCS.mjs +1 -0
  29. package/dist/inspect.d.mts +7 -7
  30. package/dist/inspect.mjs +3 -2
  31. package/dist/jsx-dev-runtime.d.mts +1 -1
  32. package/dist/jsx-runtime.d.mts +1 -1
  33. package/dist/lint.mjs +10 -6
  34. package/dist/memory-CWlqhS7l.mjs +136 -0
  35. package/dist/memory-DwDhfFWK.d.mts +50 -0
  36. package/dist/project.mjs +3 -3
  37. package/dist/{run-CofJEdYx.mjs → run-wYty_Lwo.mjs} +2 -2
  38. package/dist/{runtime-CdNJ0UBm.d.mts → runtime-DOBYM6g4.d.mts} +1 -1
  39. package/dist/{input-z_35Jwfn.mjs → session-DgukhR_7.mjs} +20 -20
  40. package/dist/{sources-DNnzyCYf.mjs → sources-Duzj6lhV.mjs} +2 -2
  41. package/dist/{src-536arXjV.mjs → src-DSl1eNB1.mjs} +14 -292
  42. package/dist/testing.d.mts +4 -50
  43. package/dist/testing.mjs +3 -87
  44. package/dist/{types-VZVWwqCg.d.mts → types-BM4shh8K.d.mts} +259 -259
  45. package/dist/{types-xXfyk56Q.d.mts → types-BUwDHKXm.d.mts} +1377 -1377
  46. package/dist/{types-CQueODzo.d.mts → types-CefgYzFt.d.mts} +2 -2
  47. package/dist/{types-DUMoYPYe.d.mts → types-DAdwEJMp.d.mts} +2 -2
  48. package/dist/{types-B0v5VVa3.d.mts → types-ZQLYXo5X.d.mts} +304 -304
  49. package/dist/types-hQgI_wrq.d.mts +544 -0
  50. package/dist/visual.d.mts +6 -6
  51. package/dist/visual.mjs +5 -5
  52. package/llms.txt +119 -43
  53. package/package.json +30 -2
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
- import { Ct as to, N as types_d_exports$16, Q as DescriptionNode, S as types_d_exports$11, St as slot, Wt as types_d_exports$14, Zt as types_d_exports$9, fn as types_d_exports$8, nn as SaveUnreadableError, p as types_d_exports$1, vn as types_d_exports$3, wt as type, xt as exit, yt as types_d_exports$5 } from "./types-B0v5VVa3.mjs";
2
- import { B as types_d_exports$6, G as Display, J as Parent, K as NineSlice, N as types_d_exports$13, S as BindOptions, W as types_d_exports$7, Y as Shape, Z as Sprite, b as defineComponent, d as popup, et as Transform, f as defineTokens, k as TextFormat, l as Box, nt as sprite, u as LocalWrite, w as CountdownValue } from "./types-xXfyk56Q.mjs";
3
- import { B as set, D as types_d_exports, F as haptic, G as tween, H as spawn, I as mark, K as use, L as parallel, M as defineAnimation, N as external, O as HapticKind, P as frames, R as play, U as spawned, V as sfx, W as stagger, h as types_d_exports$12, j as HAPTIC_KINDS, q as wait, s as types_d_exports$2, y as types_d_exports$15, z as sequence } from "./types-VZVWwqCg.mjs";
4
- import { a as types_d_exports$4 } from "./types-CQueODzo.mjs";
5
- import { $ as uiPlugin, A as Pointer, B as Layer, C as defineScene, Ct as label, D as DropTarget, E as Draggable, F as Tappable, G as resource, H as Tree, I as Touchable, J as guide, K as system, L as Traceable, M as Pressable, N as Pressed, O as Held, P as Swipeable, Q as worldPlugin, R as Traced, S as Frames, St as defineTextStyles, T as load, U as component, V as Order, W as mut, X as schedule, Y as hint, Z as defineFeature, _ as defineStyle, _t as animPlugin, a as defineEmitter, at as BackResult, b as AnimPlayer, bt as Text, c as Alpha, ct as modelPlugin, d as Displacement, dt as i18nPlugin, et as timePlugin, f as Glow, ft as flowPlugin, g as resolve, gt as assetsPlugin, h as music, ht as audioPlugin, i as screen, it as platformPlugin, j as PointerOver, k as Hovered, l as Blur, lt as lifecyclePlugin, m as Outline, mt as clockPlugin, n as createPlugin, nt as scenesPlugin, o as Emitter, ot as PlatformProvider, p as Noise, pt as effectsPlugin, q as tag, r as defineGame, rt as rendererPlugin, s as defineFilter, st as types_d_exports$10, t as createApp, tt as textPlugin, u as ColorMatrix, ut as inputPlugin, v as tr, vt as projection, w as defineBundles, x as Animation, xt as bind, y as defineMotion, yt as Countdown, z as Exiting } from "./index-BO9kZzY3.mjs";
1
+ import { $ as DescriptionNode, $t as types_d_exports$9, C as types_d_exports$11, Ct as slot, Kt as types_d_exports$3, P as types_d_exports$16, St as exit, Tt as type, bt as types_d_exports$5, in as SaveUnreadableError, m as types_d_exports$1, mn as types_d_exports$8, wt as to, yn as types_d_exports$14 } from "./types-ZQLYXo5X.mjs";
2
+ import { B as sequence, F as frames, G as stagger, H as sfx, I as haptic, J as wait, K as tween, L as mark, M as HAPTIC_KINDS, N as defineAnimation, O as types_d_exports, P as external, R as parallel, U as spawn, V as set, W as spawned, b as types_d_exports$12, f as types_d_exports$2, i as types_d_exports$15, k as HapticKind, q as use, z as play } from "./types-BM4shh8K.mjs";
3
+ import { a as types_d_exports$4 } from "./types-CefgYzFt.mjs";
4
+ import { C as TextFormat, D as types_d_exports$13, H as Transform, I as Parent, L as Shape, M as types_d_exports$7, N as Display, O as defineComponent, P as NineSlice, W as sprite, Z as types_d_exports$6, d as popup, f as defineTokens, g as BindOptions, l as Box, u as LocalWrite, v as CountdownValue, z as Sprite } from "./types-BUwDHKXm.mjs";
5
+ import { $ as uiPlugin, A as Pointer, B as Layer, C as defineScene, Ct as label, D as DropTarget, E as Draggable, F as Tappable, G as resource, H as Tree, I as Touchable, J as guide, K as system, L as Traceable, M as Pressable, N as Pressed, O as Held, P as Swipeable, Q as worldPlugin, R as Traced, S as Frames, St as defineTextStyles, T as load, U as component, V as Order, W as mut, X as schedule, Y as hint, Z as defineFeature, _ as defineStyle, _t as animPlugin, a as defineEmitter, at as BackResult, b as AnimPlayer, bt as Text, c as Alpha, ct as modelPlugin, d as Displacement, dt as i18nPlugin, et as timePlugin, f as Glow, ft as flowPlugin, g as resolve, gt as assetsPlugin, h as music, ht as audioPlugin, i as screen, it as platformPlugin, j as PointerOver, k as Hovered, l as Blur, lt as lifecyclePlugin, m as Outline, mt as clockPlugin, n as createPlugin, nt as scenesPlugin, o as Emitter, ot as PlatformProvider, p as Noise, pt as effectsPlugin, q as tag, r as defineGame, rt as rendererPlugin, s as defineFilter, st as types_d_exports$10, t as createApp, tt as textPlugin, u as ColorMatrix, ut as inputPlugin, v as tr, vt as projection, w as defineBundles, x as Animation, xt as bind, y as defineMotion, yt as Countdown, z as Exiting } from "./index-xxSxKJJW.mjs";
6
6
  export { 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, type DescriptionNode, Displacement, Display, Draggable, DropTarget, types_d_exports$4 as Effects, Emitter, Exiting, types_d_exports$5 as Flow, Frames, Glow, HAPTIC_KINDS, type HapticKind, Held, Hovered, types_d_exports$6 as I18n, types_d_exports$7 as Input, Layer, types_d_exports$8 as Lifecycle, LocalWrite, types_d_exports$9 as Model, NineSlice, Noise, Order, Outline, Parent, types_d_exports$10 as Platform, type PlatformProvider, Pointer, PointerOver, Pressable, Pressed, types_d_exports$11 as Renderer, SaveUnreadableError, types_d_exports$12 as Scenes, Shape, Sprite, Swipeable, Tappable, Text, type TextFormat, types_d_exports$13 as TextTypes, types_d_exports$14 as Time, Touchable, Traceable, Traced, Transform, Tree, types_d_exports$15 as Ui, types_d_exports$16 as World, animPlugin, assetsPlugin, audioPlugin, bind, clockPlugin, component, createApp, createPlugin, defineAnimation, defineBundles, defineComponent, defineEmitter, defineFeature, defineFilter, defineGame, defineMotion, defineScene, defineStyle, defineTextStyles, defineTokens, effectsPlugin, exit, external, flowPlugin, frames, guide, haptic, hint, i18nPlugin, inputPlugin, label, lifecyclePlugin, load, mark, modelPlugin, music, mut, parallel, platformPlugin, play, popup, projection, rendererPlugin, resolve, resource, scenesPlugin, schedule, screen, sequence, set, sfx, slot, spawn, spawned, sprite, stagger, 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, A as types_exports$3, At as defineFilter, B as defineStyle, Bt as flowPlugin, C as types_exports$10, Ct as Alpha, D as types_exports$6, Dt as Glow, E as types_exports$7, Et as Displacement, F as resolve, Ft as AnimPlayer, G as external, Gt as modelPlugin, H as platformPlugin, Ht as slot, I as Box, It as Animation, J as mark, K as frames, Kt as SaveUnreadableError, L as LocalWrite, Lt as Frames, M as types_exports$1, Mt as scenesPlugin, N as types_exports, Nt as assetsPlugin, O as types_exports$5, Ot as Noise, P as uiPlugin, Pt as animPlugin, Q as set, R as popup, Rt as rendererPlugin, S as types_exports$11, St as Emitter, T as types_exports$8, Tt as ColorMatrix, U as HAPTIC_KINDS, Ut as to, V as textPlugin, Vt as exit, W as defineAnimation, Wt as type, X as play, Xt as timePlugin, Y as parallel, Yt as lifecyclePlugin, Z as sequence, Zt as clockPlugin, _ as types_exports$16, _t as Touchable, a as defineMotion, at as wait, b as types_exports$13, bt as i18nPlugin, c as schedule, ct as DropTarget, d as tr, dt as Pointer, et as spawn, f as defineFeature, ft as PointerOver, g as load, gt as Tappable, h as defineBundles, ht as Swipeable, i as screen, it as use, j as types_exports$2, jt as audioPlugin, k as types_exports$4, kt as Outline, l as projection, lt as Held, m as music, mt as Pressed, n as createPlugin, nt as stagger, o as guide, ot as inputPlugin, p as defineEmitter, pt as Pressable, q as haptic, r as defineGame, rt as tween, s as hint, st as Draggable, t as createApp, tt as spawned, u as defineScene, ut as Hovered, v as types_exports$15, vt as Traceable, w as types_exports$9, wt as Blur, x as types_exports$12, xt as effectsPlugin, y as types_exports$14, yt as Traced, z as defineTokens, zt as worldPlugin } from "./src-536arXjV.mjs";
1
+ import { $ as sfx, A as types_exports$3, At as defineFilter, B as defineStyle, Bt as flowPlugin, C as types_exports$10, Ct as Alpha, D as types_exports$6, Dt as Glow, E as types_exports$7, Et as Displacement, F as resolve, Ft as AnimPlayer, G as external, Gt as modelPlugin, H as platformPlugin, Ht as slot, I as Box, It as Animation, J as mark, Jt as timePlugin, K as frames, Kt as SaveUnreadableError, L as LocalWrite, Lt as Frames, M as types_exports$1, Mt as scenesPlugin, N as types_exports, Nt as assetsPlugin, O as types_exports$5, Ot as Noise, P as uiPlugin, Pt as animPlugin, Q as set, R as popup, Rt as rendererPlugin, S as types_exports$11, St as Emitter, T as types_exports$8, Tt as ColorMatrix, U as HAPTIC_KINDS, Ut as to, V as textPlugin, Vt as exit, W as defineAnimation, Wt as type, X as play, Y as parallel, Yt as clockPlugin, Z as sequence, _ as types_exports$16, _t as Touchable, a as defineMotion, at as wait, b as types_exports$13, bt as i18nPlugin, c as schedule, ct as DropTarget, d as tr, dt as Pointer, et as spawn, f as defineFeature, ft as PointerOver, g as load, gt as Tappable, h as defineBundles, ht as Swipeable, i as screen, it as use, j as types_exports$2, jt as audioPlugin, k as types_exports$4, kt as Outline, l as projection, lt as Held, m as music, mt as Pressed, n as createPlugin, nt as stagger, o as guide, ot as inputPlugin, p as defineEmitter, pt as Pressable, q as haptic, qt as lifecyclePlugin, r as defineGame, rt as tween, s as hint, st as Draggable, t as createApp, tt as spawned, u as defineScene, ut as Hovered, v as types_exports$15, vt as Traceable, w as types_exports$9, wt as Blur, x as types_exports$12, xt as effectsPlugin, y as types_exports$14, yt as Traced, z as defineTokens, zt as worldPlugin } from "./src-DSl1eNB1.mjs";
2
2
  import { A as system, C as Exiting, D as component, E as Tree, O as mut, S as sprite, T as Order, _ as Parent, b as Transform, c as Text, d as defineTextStyles, f as label, g as NineSlice, h as Display, j as tag, k as resource, l as bind, s as Countdown, v as Shape, w as Layer, y as Sprite } from "./visual-dMW8iqAE.mjs";
3
3
  import { r as defineComponent } from "./flatten-BkXuscAV.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, Displacement, Display, Draggable, DropTarget, types_exports$4 as Effects, Emitter, Exiting, types_exports$5 as Flow, Frames, Glow, HAPTIC_KINDS, Held, Hovered, types_exports$6 as I18n, types_exports$7 as Input, Layer, types_exports$8 as Lifecycle, LocalWrite, types_exports$9 as Model, NineSlice, Noise, Order, Outline, Parent, types_exports$10 as Platform, Pointer, PointerOver, Pressable, Pressed, types_exports$11 as Renderer, SaveUnreadableError, types_exports$12 as Scenes, Shape, Sprite, Swipeable, Tappable, Text, types_exports$13 as TextTypes, types_exports$14 as Time, Touchable, Traceable, Traced, Transform, Tree, types_exports$15 as Ui, types_exports$16 as World, animPlugin, assetsPlugin, audioPlugin, bind, clockPlugin, component, createApp, createPlugin, defineAnimation, defineBundles, defineComponent, defineEmitter, defineFeature, defineFilter, defineGame, defineMotion, defineScene, defineStyle, defineTextStyles, defineTokens, effectsPlugin, exit, external, flowPlugin, frames, guide, haptic, hint, i18nPlugin, inputPlugin, label, lifecyclePlugin, load, mark, modelPlugin, music, mut, parallel, platformPlugin, play, popup, projection, rendererPlugin, resolve, resource, scenesPlugin, schedule, screen, sequence, set, sfx, slot, spawn, spawned, sprite, stagger, system, tag, textPlugin, timePlugin, to, tr, tween, type, uiPlugin, use, wait, worldPlugin };
@@ -0,0 +1 @@
1
+ export {};
@@ -1,10 +1,10 @@
1
- import { Gt as Api, H as EntitySnapshot, R as ComponentSchema, U as FrameDiff, f as Usage, gt as Position, j as Explained, jt as JournalEntry, k as Api$1, kt as FlowGraph, m as Api$2, rn as Snapshot, t as Api$3, w as RenderStats, x as Under } from "./types-B0v5VVa3.mjs";
2
- import { t as HeadlessApp } from "./headless-SCQXJxQf.mjs";
3
- import { a as InputOf, c as Source, i as InputArguments, l as WatchApp, o as InputSchema, t as CheatEntry, u as WatchInput } from "./types-DUMoYPYe.mjs";
4
- import { c as UiNode } from "./types-xXfyk56Q.mjs";
5
- import { a as SoundEntry, t as AudioApi, v as UiApi } from "./types-VZVWwqCg.mjs";
6
- import { n as defineSource } from "./define-B6pHpdBi.mjs";
7
- import { n as EffectsApi, r as EffectsStats } from "./types-CQueODzo.mjs";
1
+ import { A as Api$1, At as FlowGraph, M as Explained, Mt as JournalEntry, S as Under, T as RenderStats, U as EntitySnapshot, W as FrameDiff, _t as Position, an as Snapshot, h as Api$2, p as Usage, qt as Api, t as Api$3, z as ComponentSchema } from "./types-ZQLYXo5X.mjs";
2
+ import { a as AudioApi, r as UiApi, u as SoundEntry } from "./types-BM4shh8K.mjs";
3
+ import { n as EffectsApi, r as EffectsStats } from "./types-CefgYzFt.mjs";
4
+ import { c as UiNode } from "./types-BUwDHKXm.mjs";
5
+ import { t as HeadlessApp } from "./headless-G4nuZ-xz.mjs";
6
+ import { a as InputOf, c as Source, i as InputArguments, l as WatchApp, o as InputSchema, t as CheatEntry, u as WatchInput } from "./types-DAdwEJMp.mjs";
7
+ import { n as defineSource } from "./define-CCc0ozKe.mjs";
8
8
 
9
9
  //#region src/plugins/flow/doors/read.d.ts
10
10
  /**
package/dist/inspect.mjs CHANGED
@@ -1,3 +1,4 @@
1
- import { c as defineSource } from "./input-z_35Jwfn.mjs";
2
- import { n as read, r as watch, t as sources } from "./sources-DNnzyCYf.mjs";
1
+ import { c as defineSource } from "./session-DgukhR_7.mjs";
2
+ import { n as read, r as watch, t as sources } from "./sources-Duzj6lhV.mjs";
3
+ import "./inspect-la_KkjCS.mjs";
3
4
  export { defineSource, read, sources, watch };
@@ -1,2 +1,2 @@
1
- import { a as jsxs, i as jsxDEV, n as JSX, r as jsx, t as Fragment } from "./runtime-CdNJ0UBm.mjs";
1
+ import { a as jsxs, i as jsxDEV, n as JSX, r as jsx, t as Fragment } from "./runtime-DOBYM6g4.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-CdNJ0UBm.mjs";
1
+ import { a as jsxs, n as JSX, r as jsx, t as Fragment } from "./runtime-DOBYM6g4.mjs";
2
2
  export { Fragment, type JSX, jsx, jsxs };
package/dist/lint.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import path from "node:path";
2
1
  import { readFileSync, statSync } from "node:fs";
2
+ import path from "node:path";
3
3
  //#region src/lint.ts
4
4
  /**
5
5
  * @file The lint door of the engine (subpath `./lint`): an oxlint JS plugin named `moku-game` with
@@ -20,10 +20,12 @@ const TESTS = [
20
20
  /** Dev modules: a `.dev` module is wired into the editor only. */
21
21
  const DEV_MODULES = ["**/*.dev.{ts,tsx}"];
22
22
  /**
23
- * The logic of a game: state, tables, the root flow in game.ts, core, nodes, flows, rules,
24
- * features, shared. `**` so `src/` matches too.
23
+ * The logic of a game: state, tables, the game in the root index.ts, the root flow in game.ts,
24
+ * core, nodes, flows, rules, features, shared. `**` so `src/` matches too; `index.ts` is the root
25
+ * file only.
25
26
  */
26
27
  const LOGIC = [
28
+ "index.ts",
27
29
  "**/state.ts",
28
30
  "**/tables.ts",
29
31
  "**/game.ts",
@@ -425,22 +427,24 @@ const lazyImports = importRule("No static import of pixi.js or yoga-layout; impo
425
427
  pattern: /^yoga-layout(?:\/|$)/,
426
428
  message: "L2: the ui plugin loads Yoga lazily. Use import() or import type."
427
429
  }], true);
428
- /** L13: native packages stay out of the engine-facing layers. */
429
- const nativeImports = importRule("No @moku-labs/system, @moku-labs/native or @tauri-apps/* in the engine-facing layers.", {
430
+ /** L13: a game imports no native package; config.ts names the capability, the engine page wires it. */
431
+ const nativeImports = importRule("No @moku-labs/system, @moku-labs/native or @tauri-apps/* in a game: the engine page wires them.", {
430
432
  files: [
431
433
  ...LOGIC,
434
+ "config.ts",
432
435
  "**/kit.ts",
433
436
  "**/plugins/**"
434
437
  ],
435
438
  ignores: [...DEV_MODULES, ...TESTS]
436
439
  }, [{
437
440
  pattern: /^(?:@moku-labs\/(?:system|native)(?:\/|$)|@tauri-apps\/)/,
438
- message: "L13: a native package is imported only where the platform is wired: platform-bridge.ts, native.ts or web/. Pass a PlatformProvider."
441
+ message: "L13: a game imports no native package. Name the capability in config.ts system; the engine page wires it."
439
442
  }]);
440
443
  /** Dev only: the editor and the control door stay in dev files. */
441
444
  const developmentImports = importRule("@moku-labs/editor and @moku-labs/game/control only in dev files and tests.", {
442
445
  files: ["**"],
443
446
  ignores: [
447
+ ".moku/**",
444
448
  "web/main.ts",
445
449
  "web/dev*.ts",
446
450
  "web/editor*.ts",
@@ -0,0 +1,136 @@
1
+ import { t as applyTo } from "./drafts-BawpSaVp.mjs";
2
+ //#region src/plugins/clock/system.ts
3
+ /**
4
+ * Tells whether a handle was produced by this source.
5
+ *
6
+ * @param handle - Handle given back to `clearTimer`.
7
+ * @returns `true` when the handle carries a platform timer.
8
+ * @example
9
+ * ```ts
10
+ * isSystemTimer({ timer: 7 }); // true
11
+ * isSystemTimer(7); // false: a handle of another source is ignored
12
+ * ```
13
+ */
14
+ function isSystemTimer(handle) {
15
+ return typeof handle === "object" && handle !== null && "timer" in handle;
16
+ }
17
+ /**
18
+ * Creates the system source: epoch milliseconds from the device clock and real timers.
19
+ *
20
+ * @returns A source reading `Date.now` and scheduling with `setTimeout`.
21
+ */
22
+ function systemSource() {
23
+ return {
24
+ now: () => Date.now(),
25
+ setTimer: (callback, delayMs) => ({ timer: setTimeout(callback, delayMs) }),
26
+ clearTimer: (handle) => {
27
+ if (!isSystemTimer(handle)) return;
28
+ clearTimeout(handle.timer);
29
+ }
30
+ };
31
+ }
32
+ //#endregion
33
+ //#region src/plugins/model/store/providers/memory.ts
34
+ /** Seed of a save built by `saveOf` when the caller does not pin one. */
35
+ const defaultSeed = 1;
36
+ /** The base a patch applies to when the provider was never handed a document. */
37
+ const noDocument = {};
38
+ /**
39
+ * Creates an in-memory provider that keeps what it was committed and records every call.
40
+ * It is the default when a game configures no `playerProvider`, and the double every test uses:
41
+ * `provider.calls` is the whole persistence protocol of one run, in order. The document lives as
42
+ * long as the provider does, so a second app over the same instance reads what the first one
43
+ * wrote, and nothing survives the process.
44
+ *
45
+ * `load()` reads the fixture, or everything committed since; without either, the player is new.
46
+ * `commitDurable()` resolves at once: there is no disk behind it.
47
+ *
48
+ * @param fixture - The save `load()` starts from. Omitted: a new player.
49
+ * @param fixture.state - The saved document.
50
+ * @param fixture.version - Schema version of the saved document.
51
+ * @returns A provider that keeps its document and records its calls.
52
+ * @example
53
+ * ```ts
54
+ * // A new player is saved at once. One roll reaches the provider at the next rest node.
55
+ * const provider = memory();
56
+ * const game = await createHeadless(createGame(provider));
57
+ *
58
+ * await game.walk([{ at: "home", intent: "roll" }]);
59
+ * provider.calls.map(call => call.method); // ["load", "commit", "commit"]
60
+ * ```
61
+ */
62
+ function memory(fixture) {
63
+ const calls = [];
64
+ const held = {
65
+ document: fixture?.state,
66
+ version: fixture?.version ?? 0
67
+ };
68
+ /**
69
+ * Applies the patches of one commit to the held document.
70
+ *
71
+ * @param patches - Doc patches since the last commit.
72
+ * @param version - Schema version this build writes.
73
+ * @throws {Error} When a patch names a path the held document does not have.
74
+ */
75
+ const hold = (patches, version) => {
76
+ held.document = applyTo(held.document ?? noDocument, patches);
77
+ held.version = version;
78
+ };
79
+ return {
80
+ calls,
81
+ load: async () => {
82
+ calls.push({ method: "load" });
83
+ const document = held.document;
84
+ if (document === void 0) return null;
85
+ return {
86
+ state: document,
87
+ version: held.version
88
+ };
89
+ },
90
+ commit: (patches, version) => {
91
+ calls.push({
92
+ method: "commit",
93
+ patches,
94
+ version
95
+ });
96
+ hold(patches, version);
97
+ },
98
+ commitDurable: async (patches, txId, version) => {
99
+ calls.push({
100
+ method: "commitDurable",
101
+ patches,
102
+ txId,
103
+ version
104
+ });
105
+ hold(patches, version);
106
+ },
107
+ flush: async () => {
108
+ calls.push({ method: "flush" });
109
+ }
110
+ };
111
+ }
112
+ /**
113
+ * Builds a save document from a player tree, with no rng streams drawn yet.
114
+ * Short fixtures in tests read as `saveOf({ coins: 5 })` instead of spelling out the rng branch.
115
+ *
116
+ * @param player - Player tree of the save.
117
+ * @param seed - Rng seed of the save.
118
+ * @returns The save document.
119
+ * @example
120
+ * ```ts
121
+ * // A returning player with 5 coins. The test starts from this save, not from `initialPlayer`.
122
+ * saveOf({ coins: 5 }, 42); // { player: { coins: 5 }, rng: { seed: 42, streams: {} } }
123
+ * const provider = memory({ state: saveOf({ coins: 5 }, 42), version: 1 });
124
+ * ```
125
+ */
126
+ function saveOf(player, seed = defaultSeed) {
127
+ return {
128
+ player,
129
+ rng: {
130
+ seed,
131
+ streams: {}
132
+ }
133
+ };
134
+ }
135
+ //#endregion
136
+ export { saveOf as n, systemSource as r, memory as t };
@@ -0,0 +1,50 @@
1
+ import { Xt as Json, nn as ProviderCall, rn as SaveDoc, tn as PlayerStateProvider } from "./types-ZQLYXo5X.mjs";
2
+
3
+ //#region src/plugins/model/store/providers/memory.d.ts
4
+ /**
5
+ * Creates an in-memory provider that keeps what it was committed and records every call.
6
+ * It is the default when a game configures no `playerProvider`, and the double every test uses:
7
+ * `provider.calls` is the whole persistence protocol of one run, in order. The document lives as
8
+ * long as the provider does, so a second app over the same instance reads what the first one
9
+ * wrote, and nothing survives the process.
10
+ *
11
+ * `load()` reads the fixture, or everything committed since; without either, the player is new.
12
+ * `commitDurable()` resolves at once: there is no disk behind it.
13
+ *
14
+ * @param fixture - The save `load()` starts from. Omitted: a new player.
15
+ * @param fixture.state - The saved document.
16
+ * @param fixture.version - Schema version of the saved document.
17
+ * @returns A provider that keeps its document and records its calls.
18
+ * @example
19
+ * ```ts
20
+ * // A new player is saved at once. One roll reaches the provider at the next rest node.
21
+ * const provider = memory();
22
+ * const game = await createHeadless(createGame(provider));
23
+ *
24
+ * await game.walk([{ at: "home", intent: "roll" }]);
25
+ * provider.calls.map(call => call.method); // ["load", "commit", "commit"]
26
+ * ```
27
+ */
28
+ declare function memory(fixture?: {
29
+ state: SaveDoc;
30
+ version: number;
31
+ }): PlayerStateProvider & {
32
+ calls: ProviderCall[];
33
+ };
34
+ /**
35
+ * Builds a save document from a player tree, with no rng streams drawn yet.
36
+ * Short fixtures in tests read as `saveOf({ coins: 5 })` instead of spelling out the rng branch.
37
+ *
38
+ * @param player - Player tree of the save.
39
+ * @param seed - Rng seed of the save.
40
+ * @returns The save document.
41
+ * @example
42
+ * ```ts
43
+ * // A returning player with 5 coins. The test starts from this save, not from `initialPlayer`.
44
+ * saveOf({ coins: 5 }, 42); // { player: { coins: 5 }, rng: { seed: 42, streams: {} } }
45
+ * const provider = memory({ state: saveOf({ coins: 5 }, 42), version: 1 });
46
+ * ```
47
+ */
48
+ declare function saveOf(player: Json, seed?: number): SaveDoc;
49
+ //#endregion
50
+ export { saveOf as n, memory as t };
package/dist/project.mjs CHANGED
@@ -1,8 +1,8 @@
1
- import { createBrandConsole } from "@moku-labs/common/cli";
2
- import { readFile, readdir, realpath, stat } from "node:fs/promises";
1
+ import { watch } from "node:fs";
3
2
  import path from "node:path";
3
+ import { createBrandConsole } from "@moku-labs/common/cli";
4
4
  import { createHash } from "node:crypto";
5
- import { watch } from "node:fs";
5
+ import { readFile, readdir, realpath, stat } from "node:fs/promises";
6
6
  //#region src/project/extract/scope.ts
7
7
  /**
8
8
  * Unwraps the expressions that change no value: parentheses, `as`, `satisfies`, `!` and `<T>`.
@@ -1,7 +1,7 @@
1
1
  import { a as sheetAlone } from "./capture-fpd83Mi5.mjs";
2
- import { n as isDev, r as notInstalled, t as controlRefused } from "./dev-wKLgOw7c.mjs";
2
+ import { n as isDev, r as notInstalled, t as controlRefused } from "./dev-Cc50Dk7H.mjs";
3
3
  import { n as reproBookmark } from "./headless-BsNdJs9W.mjs";
4
- import { a as isProjectionTarget, i as recordCheat, o as readTarget, r as isTainted, s as defineCommand, t as inputOrEmpty } from "./input-z_35Jwfn.mjs";
4
+ import { a as readTarget, i as isProjectionTarget, n as isTainted, o as inputOrEmpty, r as recordCheat, s as defineCommand } from "./session-DgukhR_7.mjs";
5
5
  //#region src/plugins/anim/control.ts
6
6
  /**
7
7
  * @file anim plugin — the anim command of the `/control` door: switch reduced motion. Dev builds
@@ -1,4 +1,4 @@
1
- import { a as JsxChild, m as UiIntrinsicElements, t as DescriptionNode } from "./types-xXfyk56Q.mjs";
1
+ import { a as JsxChild, m as UiIntrinsicElements, t as DescriptionNode } from "./types-BUwDHKXm.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. */
@@ -67,6 +67,25 @@ function defineCommand(command) {
67
67
  return Object.freeze(command);
68
68
  }
69
69
  //#endregion
70
+ //#region src/plugins/flow/doors/input.ts
71
+ /** The input of a call that passed none. */
72
+ const noInput = Object.freeze({});
73
+ /**
74
+ * Hands the given input on, or an empty one. `InputArguments` and `WatchInput` let a call leave
75
+ * the input out only when every field of the schema is optional, so `{}` is an input of that
76
+ * schema.
77
+ *
78
+ * @param input - The input of the call, if any.
79
+ * @returns The input to pass to the descriptor.
80
+ * @example
81
+ * ```ts
82
+ * inputOrEmpty<{ last: "number?" }>(undefined); // {}
83
+ * ```
84
+ */
85
+ function inputOrEmpty(input) {
86
+ return input ?? noInput;
87
+ }
88
+ //#endregion
70
89
  //#region src/plugins/input/target.ts
71
90
  /**
72
91
  * Tells whether the JSON a command got names a view by its projection key.
@@ -152,23 +171,4 @@ function recordCheat(app, id, input, frame) {
152
171
  sessions.set(app, session);
153
172
  }
154
173
  //#endregion
155
- //#region src/plugins/flow/doors/input.ts
156
- /** The input of a call that passed none. */
157
- const noInput = Object.freeze({});
158
- /**
159
- * Hands the given input on, or an empty one. `InputArguments` and `WatchInput` let a call leave
160
- * the input out only when every field of the schema is optional, so `{}` is an input of that
161
- * schema.
162
- *
163
- * @param input - The input of the call, if any.
164
- * @returns The input to pass to the descriptor.
165
- * @example
166
- * ```ts
167
- * inputOrEmpty<{ last: "number?" }>(undefined); // {}
168
- * ```
169
- */
170
- function inputOrEmpty(input) {
171
- return input ?? noInput;
172
- }
173
- //#endregion
174
- export { isProjectionTarget as a, defineSource as c, recordCheat as i, cheatsOf as n, readTarget as o, isTainted as r, defineCommand as s, inputOrEmpty as t };
174
+ export { readTarget as a, defineSource as c, isProjectionTarget as i, isTainted as n, inputOrEmpty as o, recordCheat as r, defineCommand as s, cheatsOf as t };
@@ -1,6 +1,6 @@
1
1
  import { i as scaleByFits, w as Layer } from "./visual-dMW8iqAE.mjs";
2
- import { r as notInstalled } from "./dev-wKLgOw7c.mjs";
3
- import { c as defineSource, n as cheatsOf, o as readTarget, r as isTainted, t as inputOrEmpty } from "./input-z_35Jwfn.mjs";
2
+ import { r as notInstalled } from "./dev-Cc50Dk7H.mjs";
3
+ import { a as readTarget, c as defineSource, n as isTainted, o as inputOrEmpty, t as cheatsOf } from "./session-DgukhR_7.mjs";
4
4
  //#region src/plugins/flow/doors/read.ts
5
5
  /**
6
6
  * @file flow/doors — `read` and `watch`, the `/inspect` side. Neither changes the game.