@moku-labs/game 0.15.23 → 0.15.24

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.
@@ -2174,17 +2174,20 @@ function isRecord(value) {
2174
2174
  }
2175
2175
  /**
2176
2176
  * 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.
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
2180
  *
2179
2181
  * @param file - Absolute path of the description.
2180
2182
  * @returns Its exports, or `undefined` when the feature brought none.
2181
2183
  * @throws {Error} When the file exists but cannot be imported.
2182
2184
  */
2183
2185
  async function importDescription(file) {
2184
- if (!await stat(file).then((entry) => entry.isFile(), () => false)) return void 0;
2186
+ const entry = await stat(file).catch(() => {});
2187
+ if (entry === void 0 || !entry.isFile()) return void 0;
2185
2188
  return await import(
2186
2189
  /* @vite-ignore */
2187
- pathToFileURL(file).href
2190
+ `${pathToFileURL(file).href}?saved=${entry.size}-${Math.round(entry.mtimeMs * 1e3)}`
2188
2191
  );
2189
2192
  }
2190
2193
  /**
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-CEMfBogh.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-B8_Uc6_n.mjs";
2
2
  export { checkStrings, compileStrings, emitKeys, emitManifest, exportStrings, importStrings, packAssets, runCli, scanAssets };
package/dist/cli.d.mts CHANGED
@@ -35,8 +35,8 @@ type KeysWatcher = {
35
35
  close(): void;
36
36
  };
37
37
  /**
38
- * What `watchKeys` is started with. The watch scans when an asset file or a strings file changes;
39
- * a folder that becomes or stops being a sub-feature scans too.
38
+ * What `watchKeys` is started with. The watch scans when an asset file, a strings file or a bundle
39
+ * description changes; a folder that becomes or stops being a sub-feature scans too.
40
40
  */
41
41
  type WatchKeysOptions = {
42
42
  /**
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-CEMfBogh.mjs";
4
+ import { a as runCli$1, i as compileStrings, n as importStrings, t as exportStrings } from "./assets-B8_Uc6_n.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";
@@ -2663,10 +2663,11 @@ async function runCommand(argv, deps) {
2663
2663
  * @file The keys watch of a game folder, behind `moku-game dev` and the editor's `watchKeys`: it
2664
2664
  * keeps `generated/` fresh while a dev page is open. A file event is only a trigger. When the
2665
2665
  * events stop for a quiet period, a batch walks the game and reads the size and the time stamp of
2666
- * every asset file and every `strings/<locale>.json`; it runs the scan of `moku-game keys` only
2667
- * when they differ from the batch before. A folder that becomes or stops being a sub-feature scans
2668
- * too: the keys and bundles of its files move between owners. After a scan it writes `.moku/assets-stamp.ts` from the
2669
- * asset files: every file with its stamp, and the ones this batch found changed, so the dev page
2666
+ * every asset file, every `strings/<locale>.json` and every bundle description (`assets.ts`); it
2667
+ * runs the scan of `moku-game keys` only when they differ from the batch before. A folder that
2668
+ * becomes or stops being a sub-feature scans too: the keys and bundles of its files move between
2669
+ * owners. After a scan it writes `.moku/assets-stamp.ts` from the asset files: every file with its
2670
+ * stamp, and the ones this batch found changed, so the dev page
2670
2671
  * reads only those again. One scan runs at a time, and a failed scan never stops the watch. A
2671
2672
  * batch that scanned is followed by one more walk: the platform reports only the first path of a
2672
2673
  * burst of writes, so a save made in the same instant as the scan's own writes under `generated/`
@@ -2679,6 +2680,8 @@ const QUIET_MS = 100;
2679
2680
  const ASSET_FILE = /\.(?:png|webp|fnt|mp3|m4a)$/i;
2680
2681
  /** A strings file: a `.json` directly in a `strings/` folder. */
2681
2682
  const STRINGS_FILE = /(?:^|\/)strings\/[^/]+\.json$/;
2683
+ /** The bundle description of a feature or a layer: its `assets.ts` (`defineBundles`). */
2684
+ const DESCRIPTION_FILE = /(?:^|\/)assets\.ts$/;
2682
2685
  /**
2683
2686
  * Lists one folder of the walk.
2684
2687
  *
@@ -2693,7 +2696,8 @@ function entriesOf(folder) {
2693
2696
  }
2694
2697
  }
2695
2698
  /**
2696
- * Tells whether a file is an input of the scan: an asset file, or a strings file.
2699
+ * Tells whether a file is an input of the scan: an asset file, a strings file, or a bundle
2700
+ * description (`assets.ts`), whose tiers and releases go into the manifest.
2697
2701
  *
2698
2702
  * @param file - The path relative to the game, with `/`.
2699
2703
  * @returns True for a file the watch stamps.
@@ -2703,11 +2707,12 @@ function entriesOf(folder) {
2703
2707
  * ```
2704
2708
  */
2705
2709
  function isInput(file) {
2706
- return ASSET_FILE.test(file) || STRINGS_FILE.test(file);
2710
+ return ASSET_FILE.test(file) || STRINGS_FILE.test(file) || DESCRIPTION_FILE.test(file);
2707
2711
  }
2708
2712
  /**
2709
2713
  * Reads one folder of the walk and the folders below it, outside the skipped ones: every asset
2710
- * file and every strings file joins the inputs with its stamp. Symlinks are not followed.
2714
+ * file, strings file and bundle description joins the inputs with its stamp. Symlinks are not
2715
+ * followed.
2711
2716
  *
2712
2717
  * @param root - The real game folder.
2713
2718
  * @param folder - The folder, relative to the game; `""` is the game folder.
@@ -2911,8 +2916,8 @@ function serialized(watch) {
2911
2916
  * Starts the keys watch of a checked game: watches the folder, runs the scan of `moku-game keys`
2912
2917
  * once, and resolves after it, so `generated/` is fresh before a page is served. The watcher
2913
2918
  * starts first: a save the platform reports during the first scan starts a batch after it. Then
2914
- * every batch of file events outside the skipped folders scans again when an asset file or a
2915
- * strings file changed. A failed scan, the first one too, goes to `onError` and the watch goes on.
2919
+ * every batch of file events outside the skipped folders scans again when an asset file, a
2920
+ * strings file or a bundle description changed. A failed scan, the first one too, goes to `onError` and the watch goes on.
2916
2921
  *
2917
2922
  * @param root - The game folder, absolute.
2918
2923
  * @param settings - The resolved config.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moku-labs/game",
3
- "version": "0.15.23",
3
+ "version": "0.15.24",
4
4
  "description": "2D puzzle game engine on TypeScript and PixiJS, built on @moku-labs/core.",
5
5
  "type": "module",
6
6
  "sideEffects": [