@al8b/runtime 0.1.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 (185) hide show
  1. package/README.md +87 -0
  2. package/dist/assets/constructors.d.mts +6 -0
  3. package/dist/assets/constructors.d.ts +6 -0
  4. package/dist/assets/constructors.js +40 -0
  5. package/dist/assets/constructors.js.map +1 -0
  6. package/dist/assets/constructors.mjs +12 -0
  7. package/dist/assets/constructors.mjs.map +1 -0
  8. package/dist/assets/index.d.mts +11 -0
  9. package/dist/assets/index.d.ts +11 -0
  10. package/dist/assets/index.js +276 -0
  11. package/dist/assets/index.js.map +1 -0
  12. package/dist/assets/index.mjs +247 -0
  13. package/dist/assets/index.mjs.map +1 -0
  14. package/dist/assets/loader.d.mts +83 -0
  15. package/dist/assets/loader.d.ts +83 -0
  16. package/dist/assets/loader.js +260 -0
  17. package/dist/assets/loader.js.map +1 -0
  18. package/dist/assets/loader.mjs +237 -0
  19. package/dist/assets/loader.mjs.map +1 -0
  20. package/dist/browser/index.js +16599 -0
  21. package/dist/browser/index.js.map +1 -0
  22. package/dist/browser/index.min.js +171 -0
  23. package/dist/constants.d.mts +16 -0
  24. package/dist/constants.d.ts +16 -0
  25. package/dist/constants.js +49 -0
  26. package/dist/constants.js.map +1 -0
  27. package/dist/constants.mjs +18 -0
  28. package/dist/constants.mjs.map +1 -0
  29. package/dist/core/api-factory.d.mts +63 -0
  30. package/dist/core/api-factory.d.ts +63 -0
  31. package/dist/core/api-factory.js +239 -0
  32. package/dist/core/api-factory.js.map +1 -0
  33. package/dist/core/api-factory.mjs +214 -0
  34. package/dist/core/api-factory.mjs.map +1 -0
  35. package/dist/core/assets-registry.d.mts +14 -0
  36. package/dist/core/assets-registry.d.ts +14 -0
  37. package/dist/core/assets-registry.js +64 -0
  38. package/dist/core/assets-registry.js.map +1 -0
  39. package/dist/core/assets-registry.mjs +41 -0
  40. package/dist/core/assets-registry.mjs.map +1 -0
  41. package/dist/core/controller.d.mts +109 -0
  42. package/dist/core/controller.d.ts +109 -0
  43. package/dist/core/controller.js +1782 -0
  44. package/dist/core/controller.js.map +1 -0
  45. package/dist/core/controller.mjs +1758 -0
  46. package/dist/core/controller.mjs.map +1 -0
  47. package/dist/core/debug-logger.d.mts +35 -0
  48. package/dist/core/debug-logger.d.ts +35 -0
  49. package/dist/core/debug-logger.js +177 -0
  50. package/dist/core/debug-logger.js.map +1 -0
  51. package/dist/core/debug-logger.mjs +154 -0
  52. package/dist/core/debug-logger.mjs.map +1 -0
  53. package/dist/core/error-handler.d.mts +25 -0
  54. package/dist/core/error-handler.d.ts +25 -0
  55. package/dist/core/error-handler.js +106 -0
  56. package/dist/core/error-handler.js.map +1 -0
  57. package/dist/core/error-handler.mjs +81 -0
  58. package/dist/core/error-handler.mjs.map +1 -0
  59. package/dist/core/index.d.mts +14 -0
  60. package/dist/core/index.d.ts +14 -0
  61. package/dist/core/index.js +1782 -0
  62. package/dist/core/index.js.map +1 -0
  63. package/dist/core/index.mjs +1757 -0
  64. package/dist/core/index.mjs.map +1 -0
  65. package/dist/hot-reload/index.d.mts +7 -0
  66. package/dist/hot-reload/index.d.ts +7 -0
  67. package/dist/hot-reload/index.js +103 -0
  68. package/dist/hot-reload/index.js.map +1 -0
  69. package/dist/hot-reload/index.mjs +78 -0
  70. package/dist/hot-reload/index.mjs.map +1 -0
  71. package/dist/hot-reload/updater.d.mts +33 -0
  72. package/dist/hot-reload/updater.d.ts +33 -0
  73. package/dist/hot-reload/updater.js +101 -0
  74. package/dist/hot-reload/updater.js.map +1 -0
  75. package/dist/hot-reload/updater.mjs +78 -0
  76. package/dist/hot-reload/updater.mjs.map +1 -0
  77. package/dist/index.d.mts +24 -0
  78. package/dist/index.d.ts +24 -0
  79. package/dist/index.js +1859 -0
  80. package/dist/index.js.map +1 -0
  81. package/dist/index.mjs +1817 -0
  82. package/dist/index.mjs.map +1 -0
  83. package/dist/input/index.d.mts +2 -0
  84. package/dist/input/index.d.ts +2 -0
  85. package/dist/input/index.js +79 -0
  86. package/dist/input/index.js.map +1 -0
  87. package/dist/input/index.mjs +54 -0
  88. package/dist/input/index.mjs.map +1 -0
  89. package/dist/input/manager.d.mts +37 -0
  90. package/dist/input/manager.d.ts +37 -0
  91. package/dist/input/manager.js +77 -0
  92. package/dist/input/manager.js.map +1 -0
  93. package/dist/input/manager.mjs +54 -0
  94. package/dist/input/manager.mjs.map +1 -0
  95. package/dist/loop/game-loop.d.mts +63 -0
  96. package/dist/loop/game-loop.d.ts +63 -0
  97. package/dist/loop/game-loop.js +156 -0
  98. package/dist/loop/game-loop.js.map +1 -0
  99. package/dist/loop/game-loop.mjs +131 -0
  100. package/dist/loop/game-loop.mjs.map +1 -0
  101. package/dist/loop/index.d.mts +1 -0
  102. package/dist/loop/index.d.ts +1 -0
  103. package/dist/loop/index.js +156 -0
  104. package/dist/loop/index.js.map +1 -0
  105. package/dist/loop/index.mjs +131 -0
  106. package/dist/loop/index.mjs.map +1 -0
  107. package/dist/storage/index.d.mts +1 -0
  108. package/dist/storage/index.d.ts +1 -0
  109. package/dist/storage/index.js +31 -0
  110. package/dist/storage/index.js.map +1 -0
  111. package/dist/storage/index.mjs +6 -0
  112. package/dist/storage/index.mjs.map +1 -0
  113. package/dist/system/api.d.mts +28 -0
  114. package/dist/system/api.d.ts +28 -0
  115. package/dist/system/api.js +126 -0
  116. package/dist/system/api.js.map +1 -0
  117. package/dist/system/api.mjs +101 -0
  118. package/dist/system/api.mjs.map +1 -0
  119. package/dist/system/index.d.mts +2 -0
  120. package/dist/system/index.d.ts +2 -0
  121. package/dist/system/index.js +126 -0
  122. package/dist/system/index.js.map +1 -0
  123. package/dist/system/index.mjs +101 -0
  124. package/dist/system/index.mjs.map +1 -0
  125. package/dist/types/assets.d.mts +43 -0
  126. package/dist/types/assets.d.ts +43 -0
  127. package/dist/types/assets.js +19 -0
  128. package/dist/types/assets.js.map +1 -0
  129. package/dist/types/assets.mjs +1 -0
  130. package/dist/types/assets.mjs.map +1 -0
  131. package/dist/types/bridge.d.mts +66 -0
  132. package/dist/types/bridge.d.ts +66 -0
  133. package/dist/types/bridge.js +19 -0
  134. package/dist/types/bridge.js.map +1 -0
  135. package/dist/types/bridge.mjs +1 -0
  136. package/dist/types/bridge.mjs.map +1 -0
  137. package/dist/types/index.d.mts +6 -0
  138. package/dist/types/index.d.ts +6 -0
  139. package/dist/types/index.js +19 -0
  140. package/dist/types/index.js.map +1 -0
  141. package/dist/types/index.mjs +1 -0
  142. package/dist/types/index.mjs.map +1 -0
  143. package/dist/types/runtime.d.mts +71 -0
  144. package/dist/types/runtime.d.ts +71 -0
  145. package/dist/types/runtime.js +19 -0
  146. package/dist/types/runtime.js.map +1 -0
  147. package/dist/types/runtime.mjs +1 -0
  148. package/dist/types/runtime.mjs.map +1 -0
  149. package/dist/types/vm.d.mts +1 -0
  150. package/dist/types/vm.d.ts +1 -0
  151. package/dist/types/vm.js +19 -0
  152. package/dist/types/vm.js.map +1 -0
  153. package/dist/types/vm.mjs +1 -0
  154. package/dist/types/vm.mjs.map +1 -0
  155. package/dist/utils/deep-clone.d.mts +14 -0
  156. package/dist/utils/deep-clone.d.ts +14 -0
  157. package/dist/utils/deep-clone.js +42 -0
  158. package/dist/utils/deep-clone.js.map +1 -0
  159. package/dist/utils/deep-clone.mjs +19 -0
  160. package/dist/utils/deep-clone.mjs.map +1 -0
  161. package/dist/utils/index.d.mts +3 -0
  162. package/dist/utils/index.d.ts +3 -0
  163. package/dist/utils/index.js +156 -0
  164. package/dist/utils/index.js.map +1 -0
  165. package/dist/utils/index.mjs +129 -0
  166. package/dist/utils/index.mjs.map +1 -0
  167. package/dist/utils/object-pool.d.mts +66 -0
  168. package/dist/utils/object-pool.d.ts +66 -0
  169. package/dist/utils/object-pool.js +113 -0
  170. package/dist/utils/object-pool.js.map +1 -0
  171. package/dist/utils/object-pool.mjs +90 -0
  172. package/dist/utils/object-pool.mjs.map +1 -0
  173. package/dist/utils/shallow-equal.d.mts +15 -0
  174. package/dist/utils/shallow-equal.d.ts +15 -0
  175. package/dist/utils/shallow-equal.js +53 -0
  176. package/dist/utils/shallow-equal.js.map +1 -0
  177. package/dist/utils/shallow-equal.mjs +30 -0
  178. package/dist/utils/shallow-equal.mjs.map +1 -0
  179. package/dist/vm/index.d.mts +1 -0
  180. package/dist/vm/index.d.ts +1 -0
  181. package/dist/vm/index.js +37 -0
  182. package/dist/vm/index.js.map +1 -0
  183. package/dist/vm/index.mjs +9 -0
  184. package/dist/vm/index.mjs.map +1 -0
  185. package/package.json +52 -0
package/README.md ADDED
@@ -0,0 +1,87 @@
1
+ # @al8b/runtime
2
+
3
+ Browser runtime facade for AL8B games. It owns asset loading, VM bootstrap, the frame loop, script-facing globals, bridge-based host integration, hot reload integration, and runtime lifecycle control.
4
+
5
+ ## Public API
6
+
7
+ - `createRuntime`
8
+ - `RuntimeController`
9
+ - `RuntimeBridge`
10
+ - `RuntimeSnapshot`
11
+ - `RuntimeSessionSnapshot`
12
+ - Re-exports from `assets`, `core`, `hot-reload`, `input`, `loop`, `storage`, `system`, `types`, `utils`, and `vm`
13
+
14
+ ## Runtime Responsibilities
15
+
16
+ - Build the global script API (`screen`, `audio`, `input`, `player`, `scene`, `router`, `system`)
17
+ - Expose host-facing built-ins (`host`, `session`, `memory`)
18
+ - Load assets and compiled routine artifacts or development sources
19
+ - Coordinate the game loop and debug time-machine hooks
20
+ - Route runtime errors, warnings, and bridge events back to the host shell
21
+
22
+ ## Host Bridge
23
+
24
+ Use `bridge` to connect the runtime to your app shell, backend, or realtime layer.
25
+
26
+ ```ts
27
+ import { createRuntime, type RuntimeBridge } from "@al8b/runtime";
28
+
29
+ const bridge: RuntimeBridge = {
30
+ emit(name, payload) {
31
+ console.log("game event", name, payload);
32
+ },
33
+ request(name, payload) {
34
+ return fetch(`/api/runtime/${name}`, {
35
+ method: "POST",
36
+ body: JSON.stringify(payload)
37
+ }).then((response) => response.json());
38
+ },
39
+ getSession() {
40
+ return {
41
+ user: { id: "user-1" },
42
+ game: { id: "hello" }
43
+ };
44
+ }
45
+ };
46
+
47
+ const runtime = createRuntime({
48
+ canvas,
49
+ sources,
50
+ resources,
51
+ bridge
52
+ });
53
+ ```
54
+
55
+ LootiScript can use:
56
+
57
+ - `host.emit(name, payload)`
58
+ - `host.request(name, payload, callback)`
59
+ - `session.user()`, `session.player()`, `session.game()`, `session.room()`
60
+ - `memory.export()`, `memory.import(snapshot)`, `memory.reset()`, `memory.save(meta, callback)`, `memory.load(meta, callback)`
61
+
62
+ ## Runtime Lifecycle
63
+
64
+ `RuntimeController` now exposes lifecycle and state transfer primitives needed by host apps:
65
+
66
+ - `start()`
67
+ - `stop()`
68
+ - `resume()`
69
+ - `reset(options?)`
70
+ - `exportSnapshot()`
71
+ - `importSnapshot(snapshot)`
72
+ - `sendHostEvent(event)`
73
+ - `getSession()`
74
+
75
+ ## Notes
76
+
77
+ - This package is the integration point for most `@al8b/*` engine packages.
78
+ - `createRuntime()` is the only supported top-level runtime constructor.
79
+ - Backend access, auth, multiplayer transport, and hub UX stay in the host app or bridge layer, not in runtime core.
80
+
81
+ ## Scripts
82
+
83
+ ```bash
84
+ bun run build
85
+ bun run test
86
+ bun run clean
87
+ ```
@@ -0,0 +1,6 @@
1
+ export { Sound } from '@al8b/audio';
2
+ export { TileMap } from '@al8b/map';
3
+ export { Image } from '@al8b/image';
4
+ export { Sprite } from '@al8b/sprites';
5
+ import '@al8b/vm';
6
+ import '@al8b/io';
@@ -0,0 +1,6 @@
1
+ export { Sound } from '@al8b/audio';
2
+ export { TileMap } from '@al8b/map';
3
+ export { Image } from '@al8b/image';
4
+ export { Sprite } from '@al8b/sprites';
5
+ import '@al8b/vm';
6
+ import '@al8b/io';
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/assets/constructors.ts
21
+ var constructors_exports = {};
22
+ __export(constructors_exports, {
23
+ Image: () => import_image.Image,
24
+ Sound: () => import_audio.Sound,
25
+ Sprite: () => import_sprites.Sprite,
26
+ TileMap: () => import_map.TileMap
27
+ });
28
+ module.exports = __toCommonJS(constructors_exports);
29
+ var import_audio = require("@al8b/audio");
30
+ var import_map = require("@al8b/map");
31
+ var import_image = require("@al8b/image");
32
+ var import_sprites = require("@al8b/sprites");
33
+ // Annotate the CommonJS export names for ESM import in node:
34
+ 0 && (module.exports = {
35
+ Image,
36
+ Sound,
37
+ Sprite,
38
+ TileMap
39
+ });
40
+ //# sourceMappingURL=constructors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/assets/constructors.ts"],"sourcesContent":["/**\n * Dynamic asset constructors\n *\n * Provides constructors for creating assets at runtime\n */\n\nimport { Sound } from \"@al8b/audio\";\nimport { TileMap } from \"@al8b/map\";\nimport { Image } from \"@al8b/image\";\nimport { Sprite } from \"@al8b/sprites\";\n\n/**\n * Export constructors for game code\n */\nexport { Image, Sprite, TileMap, Sound };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;AAMA,mBAAsB;AACtB,iBAAwB;AACxB,mBAAsB;AACtB,qBAAuB;","names":[]}
@@ -0,0 +1,12 @@
1
+ // src/assets/constructors.ts
2
+ import { Sound } from "@al8b/audio";
3
+ import { TileMap } from "@al8b/map";
4
+ import { Image } from "@al8b/image";
5
+ import { Sprite } from "@al8b/sprites";
6
+ export {
7
+ Image,
8
+ Sound,
9
+ Sprite,
10
+ TileMap
11
+ };
12
+ //# sourceMappingURL=constructors.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/assets/constructors.ts"],"sourcesContent":["/**\n * Dynamic asset constructors\n *\n * Provides constructors for creating assets at runtime\n */\n\nimport { Sound } from \"@al8b/audio\";\nimport { TileMap } from \"@al8b/map\";\nimport { Image } from \"@al8b/image\";\nimport { Sprite } from \"@al8b/sprites\";\n\n/**\n * Export constructors for game code\n */\nexport { Image, Sprite, TileMap, Sound };\n"],"mappings":";AAMA,SAASA,aAAa;AACtB,SAASC,eAAe;AACxB,SAASC,aAAa;AACtB,SAASC,cAAc;","names":["Sound","TileMap","Image","Sprite"]}
@@ -0,0 +1,11 @@
1
+ export { Sound } from '@al8b/audio';
2
+ export { TileMap } from '@al8b/map';
3
+ export { Image } from '@al8b/image';
4
+ export { Sprite } from '@al8b/sprites';
5
+ export { AssetLoader } from './loader.mjs';
6
+ import '../types/assets.mjs';
7
+ import '../types/runtime.mjs';
8
+ import '@al8b/framework-shared';
9
+ import '@al8b/vm';
10
+ import '../types/bridge.mjs';
11
+ import '@al8b/time';
@@ -0,0 +1,11 @@
1
+ export { Sound } from '@al8b/audio';
2
+ export { TileMap } from '@al8b/map';
3
+ export { Image } from '@al8b/image';
4
+ export { Sprite } from '@al8b/sprites';
5
+ export { AssetLoader } from './loader.js';
6
+ import '../types/assets.js';
7
+ import '../types/runtime.js';
8
+ import '@al8b/framework-shared';
9
+ import '@al8b/vm';
10
+ import '../types/bridge.js';
11
+ import '@al8b/time';
@@ -0,0 +1,276 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/assets/index.ts
22
+ var assets_exports = {};
23
+ __export(assets_exports, {
24
+ AssetLoader: () => AssetLoader,
25
+ Image: () => import_image.Image,
26
+ Sound: () => import_audio.Sound,
27
+ Sprite: () => import_sprites.Sprite,
28
+ TileMap: () => import_map.TileMap
29
+ });
30
+ module.exports = __toCommonJS(assets_exports);
31
+
32
+ // src/assets/constructors.ts
33
+ var import_audio = require("@al8b/audio");
34
+ var import_map = require("@al8b/map");
35
+ var import_image = require("@al8b/image");
36
+ var import_sprites = require("@al8b/sprites");
37
+
38
+ // src/assets/loader.ts
39
+ var import_audio2 = require("@al8b/audio");
40
+
41
+ // src/constants.ts
42
+ var DEFAULT_FPS = 60;
43
+ var FRAME_TIME_MS = 1e3 / DEFAULT_FPS;
44
+ var DEFAULT_BLOCK_SIZE = 16;
45
+ var LOADING_BAR_THROTTLE_MS = 16;
46
+ var ASSET_LOAD_TIMEOUT_MS = 3e4;
47
+
48
+ // src/assets/loader.ts
49
+ var import_map2 = require("@al8b/map");
50
+ var import_sprites2 = require("@al8b/sprites");
51
+ function withTimeout(promise, ms) {
52
+ return Promise.race([
53
+ promise,
54
+ new Promise((_, reject) => setTimeout(() => reject(new Error(`Asset load timed out after ${ms}ms`)), ms))
55
+ ]);
56
+ }
57
+ __name(withTimeout, "withTimeout");
58
+ var AssetLoader = class {
59
+ static {
60
+ __name(this, "AssetLoader");
61
+ }
62
+ url;
63
+ resources;
64
+ collections;
65
+ loadingBarTime = null;
66
+ audioCore;
67
+ listener;
68
+ constructor(url, resources, audioCore, listener) {
69
+ this.url = url;
70
+ this.resources = resources;
71
+ this.audioCore = audioCore;
72
+ this.listener = listener;
73
+ this.collections = {
74
+ sprites: {},
75
+ maps: {},
76
+ sounds: {},
77
+ music: {},
78
+ assets: {}
79
+ };
80
+ }
81
+ /**
82
+ * Load all assets
83
+ */
84
+ async loadAll() {
85
+ await Promise.all([
86
+ this.loadSprites(),
87
+ this.loadMaps(),
88
+ this.loadSounds(),
89
+ this.loadMusic(),
90
+ this.loadGenericAssets()
91
+ ]);
92
+ return this.collections;
93
+ }
94
+ /**
95
+ * Load a set of callback-based assets (sprites or maps) with timeout and placeholder fallback.
96
+ */
97
+ async loadCallbackAssets(resources, urlPrefix, collectionKey, load, createPlaceholder) {
98
+ if (!resources) return;
99
+ const promises = resources.map((res) => new Promise((resolve) => {
100
+ const name = res.file.split(".")[0].replace(/-/g, "/");
101
+ const url = `${this.url}${urlPrefix}/${res.file}?v=${res.version || 0}`;
102
+ try {
103
+ const inner = new Promise((onReady) => {
104
+ this.collections[collectionKey][name] = load(url, res, onReady);
105
+ });
106
+ withTimeout(inner, ASSET_LOAD_TIMEOUT_MS).then(resolve).catch((err) => {
107
+ this.listener?.log?.(`[AssetLoader] Failed to load ${collectionKey.slice(0, -1)} "${name}": ${String(err)}`);
108
+ this.collections[collectionKey][name] = createPlaceholder(name, res);
109
+ resolve();
110
+ });
111
+ } catch (err) {
112
+ this.listener?.log?.(`[AssetLoader] Failed to load ${collectionKey.slice(0, -1)} "${name}": ${String(err)}`);
113
+ this.collections[collectionKey][name] = createPlaceholder(name, res);
114
+ resolve();
115
+ }
116
+ }));
117
+ await Promise.all(promises);
118
+ }
119
+ /**
120
+ * Load sprites
121
+ */
122
+ async loadSprites() {
123
+ await this.loadCallbackAssets(this.resources.images, "sprites", "sprites", (url, img, onReady) => (0, import_sprites2.LoadSprite)(url, img.properties, onReady), (name, img) => ({
124
+ name,
125
+ ready: false,
126
+ frames: [],
127
+ fps: img.properties?.fps || 5,
128
+ width: 0,
129
+ height: 0
130
+ }));
131
+ }
132
+ /**
133
+ * Load maps
134
+ */
135
+ async loadMaps() {
136
+ await this.loadCallbackAssets(this.resources.maps, "maps", "maps", (url, _mapRes, onReady) => (0, import_map2.LoadMap)(url, this.collections.sprites, onReady), (name) => ({
137
+ name,
138
+ ready: false,
139
+ width: 0,
140
+ height: 0,
141
+ block_width: DEFAULT_BLOCK_SIZE,
142
+ block_height: DEFAULT_BLOCK_SIZE,
143
+ data: []
144
+ }));
145
+ }
146
+ /**
147
+ * Load sounds
148
+ */
149
+ async loadSounds() {
150
+ if (!this.resources.sounds) return;
151
+ const promises = this.resources.sounds.map((sound) => {
152
+ return new Promise((resolve) => {
153
+ const name = sound.file.split(".")[0];
154
+ const url = `${this.url}sounds/${sound.file}?v=${sound.version || 0}`;
155
+ try {
156
+ const soundInstance = new import_audio2.Sound(this.audioCore, url);
157
+ this.collections.sounds[name] = soundInstance;
158
+ resolve();
159
+ } catch (err) {
160
+ this.listener?.log?.(`[AssetLoader] Failed to load sound "${name}": ${String(err)}`);
161
+ this.collections.sounds[name] = new import_audio2.Sound(this.audioCore, url);
162
+ resolve();
163
+ }
164
+ });
165
+ });
166
+ await Promise.all(promises);
167
+ }
168
+ /**
169
+ * Load music
170
+ */
171
+ async loadMusic() {
172
+ if (!this.resources.music) return;
173
+ const promises = this.resources.music.map((mus) => {
174
+ return new Promise((resolve) => {
175
+ const name = mus.file.split(".")[0];
176
+ const url = `${this.url}music/${mus.file}?v=${mus.version || 0}`;
177
+ try {
178
+ const musicInstance = new import_audio2.Music(this.audioCore, url);
179
+ this.collections.music[name] = musicInstance;
180
+ resolve();
181
+ } catch (err) {
182
+ this.listener?.log?.(`[AssetLoader] Failed to load music "${name}": ${String(err)}`);
183
+ this.collections.music[name] = new import_audio2.Music(this.audioCore, url);
184
+ resolve();
185
+ }
186
+ });
187
+ });
188
+ await Promise.all(promises);
189
+ }
190
+ /**
191
+ * Load generic assets
192
+ */
193
+ async loadGenericAssets() {
194
+ if (!this.resources.assets) return;
195
+ for (const asset of this.resources.assets) {
196
+ const name = asset.file.split(".")[0].replace(/-/g, "/");
197
+ this.collections.assets[name] = {
198
+ name,
199
+ file: asset.file,
200
+ version: asset.version
201
+ };
202
+ }
203
+ }
204
+ /**
205
+ * Check if all assets are ready
206
+ */
207
+ isReady() {
208
+ return this.countReady() === this.countTotal();
209
+ }
210
+ /**
211
+ * Get loading progress (0-1)
212
+ */
213
+ getProgress() {
214
+ const total = this.countTotal();
215
+ if (total === 0) return 1;
216
+ return this.countReady() / total;
217
+ }
218
+ /**
219
+ * Count total assets
220
+ */
221
+ countTotal() {
222
+ let count = 0;
223
+ count += Object.keys(this.collections.sprites).length;
224
+ count += Object.keys(this.collections.maps).length;
225
+ count += Object.keys(this.collections.sounds).length;
226
+ count += Object.keys(this.collections.music).length;
227
+ return count;
228
+ }
229
+ /**
230
+ * Count ready assets
231
+ */
232
+ countReady() {
233
+ let ready = 0;
234
+ for (const sprite of Object.values(this.collections.sprites)) {
235
+ if (sprite.ready) ready++;
236
+ }
237
+ for (const map of Object.values(this.collections.maps)) {
238
+ if (map.ready) ready++;
239
+ }
240
+ for (const sound of Object.values(this.collections.sounds)) {
241
+ if (sound.ready) ready++;
242
+ }
243
+ for (const mus of Object.values(this.collections.music)) {
244
+ if (mus.ready) ready++;
245
+ }
246
+ return ready;
247
+ }
248
+ /**
249
+ * Show loading bar on screen
250
+ */
251
+ showLoadingBar(screenInterface) {
252
+ if (this.loadingBarTime && Date.now() < this.loadingBarTime + LOADING_BAR_THROTTLE_MS) {
253
+ return;
254
+ }
255
+ this.loadingBarTime = Date.now();
256
+ const progress = this.getProgress();
257
+ screenInterface.clear("#000");
258
+ screenInterface.drawRect(0, 0, 100, 10, "#DDD");
259
+ screenInterface.fillRect(-(1 - progress) * 48, 0, progress * 96, 6, "#DDD");
260
+ }
261
+ /**
262
+ * Get loaded collections
263
+ */
264
+ getCollections() {
265
+ return this.collections;
266
+ }
267
+ };
268
+ // Annotate the CommonJS export names for ESM import in node:
269
+ 0 && (module.exports = {
270
+ AssetLoader,
271
+ Image,
272
+ Sound,
273
+ Sprite,
274
+ TileMap
275
+ });
276
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/assets/index.ts","../../src/assets/constructors.ts","../../src/assets/loader.ts","../../src/constants.ts"],"sourcesContent":["/**\n * Asset management exports\n */\n\nexport {\n\tImage,\n\tTileMap,\n\tSound,\n\tSprite,\n} from \"./constructors\";\nexport { AssetLoader } from \"./loader\";\n","/**\n * Dynamic asset constructors\n *\n * Provides constructors for creating assets at runtime\n */\n\nimport { Sound } from \"@al8b/audio\";\nimport { TileMap } from \"@al8b/map\";\nimport { Image } from \"@al8b/image\";\nimport { Sprite } from \"@al8b/sprites\";\n\n/**\n * Export constructors for game code\n */\nexport { Image, Sprite, TileMap, Sound };\n","/**\n * AssetLoader - Handles loading of game assets\n *\n * Responsibilities:\n * - Load sprites, maps, sounds, music\n * - Track loading progress\n * - Show loading bar\n */\n\nimport { AudioCore, Sound, Music } from \"@al8b/audio\";\nimport { ASSET_LOAD_TIMEOUT_MS, DEFAULT_BLOCK_SIZE, LOADING_BAR_THROTTLE_MS } from \"../constants\";\nimport { LoadMap } from \"@al8b/map\";\nimport { LoadSprite } from \"@al8b/sprites\";\nimport type { AssetCollections, ResourceFile, Resources } from \"../types\";\nimport type { RuntimeListener } from \"../types\";\n\n/**\n * Race a promise against a timeout.\n * Rejects with a descriptive error if `ms` elapses before the promise settles.\n */\nfunction withTimeout<T>(promise: Promise<T>, ms: number): Promise<T> {\n\treturn Promise.race([\n\t\tpromise,\n\t\tnew Promise<T>((_, reject) =>\n\t\t\tsetTimeout(() => reject(new Error(`Asset load timed out after ${ms}ms`)), ms),\n\t\t),\n\t]);\n}\n\nexport class AssetLoader {\n\tprivate url: string;\n\tprivate resources: Resources;\n\tprivate collections: AssetCollections;\n\tprivate loadingBarTime: number | null = null;\n\tprivate audioCore: AudioCore;\n\tprivate listener?: RuntimeListener;\n\n\tconstructor(url: string, resources: Resources, audioCore: AudioCore, listener?: RuntimeListener) {\n\t\tthis.url = url;\n\t\tthis.resources = resources;\n\t\tthis.audioCore = audioCore;\n\t\tthis.listener = listener;\n\t\tthis.collections = {\n\t\t\tsprites: {},\n\t\t\tmaps: {},\n\t\t\tsounds: {},\n\t\t\tmusic: {},\n\t\t\tassets: {},\n\t\t};\n\t}\n\n\t/**\n\t * Load all assets\n\t */\n\tasync loadAll(): Promise<AssetCollections> {\n\t\tawait Promise.all([\n\t\t\tthis.loadSprites(),\n\t\t\tthis.loadMaps(),\n\t\t\tthis.loadSounds(),\n\t\t\tthis.loadMusic(),\n\t\t\tthis.loadGenericAssets(),\n\t\t]);\n\n\t\treturn this.collections;\n\t}\n\n\t/**\n\t * Load a set of callback-based assets (sprites or maps) with timeout and placeholder fallback.\n\t */\n\tprivate async loadCallbackAssets<TRes extends ResourceFile>(\n\t\tresources: TRes[] | undefined,\n\t\turlPrefix: string,\n\t\tcollectionKey: \"sprites\" | \"maps\",\n\t\tload: (url: string, res: TRes, onReady: () => void) => any,\n\t\tcreatePlaceholder: (name: string, res: TRes) => any,\n\t): Promise<void> {\n\t\tif (!resources) return;\n\n\t\tconst promises = resources.map(\n\t\t\t(res) =>\n\t\t\t\tnew Promise<void>((resolve) => {\n\t\t\t\t\tconst name = res.file.split(\".\")[0].replace(/-/g, \"/\");\n\t\t\t\t\tconst url = `${this.url}${urlPrefix}/${res.file}?v=${res.version || 0}`;\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst inner = new Promise<void>((onReady) => {\n\t\t\t\t\t\t\tthis.collections[collectionKey][name] = load(url, res, onReady);\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\twithTimeout(inner, ASSET_LOAD_TIMEOUT_MS).then(resolve).catch((err) => {\n\t\t\t\t\t\t\tthis.listener?.log?.(`[AssetLoader] Failed to load ${collectionKey.slice(0, -1)} \"${name}\": ${String(err)}`);\n\t\t\t\t\t\t\tthis.collections[collectionKey][name] = createPlaceholder(name, res);\n\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tthis.listener?.log?.(`[AssetLoader] Failed to load ${collectionKey.slice(0, -1)} \"${name}\": ${String(err)}`);\n\t\t\t\t\t\tthis.collections[collectionKey][name] = createPlaceholder(name, res);\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t);\n\n\t\tawait Promise.all(promises);\n\t}\n\n\t/**\n\t * Load sprites\n\t */\n\tprivate async loadSprites(): Promise<void> {\n\t\tawait this.loadCallbackAssets(\n\t\t\tthis.resources.images,\n\t\t\t\"sprites\",\n\t\t\t\"sprites\",\n\t\t\t(url, img, onReady) => LoadSprite(url, img.properties, onReady),\n\t\t\t(name, img) => ({\n\t\t\t\tname,\n\t\t\t\tready: false,\n\t\t\t\tframes: [],\n\t\t\t\tfps: (img.properties as any)?.fps || 5,\n\t\t\t\twidth: 0,\n\t\t\t\theight: 0,\n\t\t\t}),\n\t\t);\n\t}\n\n\t/**\n\t * Load maps\n\t */\n\tprivate async loadMaps(): Promise<void> {\n\t\tawait this.loadCallbackAssets(\n\t\t\tthis.resources.maps,\n\t\t\t\"maps\",\n\t\t\t\"maps\",\n\t\t\t(url, _mapRes, onReady) => LoadMap(url, this.collections.sprites, onReady),\n\t\t\t(name) => ({\n\t\t\t\tname,\n\t\t\t\tready: false,\n\t\t\t\twidth: 0,\n\t\t\t\theight: 0,\n\t\t\t\tblock_width: DEFAULT_BLOCK_SIZE,\n\t\t\t\tblock_height: DEFAULT_BLOCK_SIZE,\n\t\t\t\tdata: [],\n\t\t\t}),\n\t\t);\n\t}\n\n\t/**\n\t * Load sounds\n\t */\n\tprivate async loadSounds(): Promise<void> {\n\t\tif (!this.resources.sounds) return;\n\n\t\tconst promises = this.resources.sounds.map((sound) => {\n\t\t\treturn new Promise<void>((resolve) => {\n\t\t\t\tconst name = sound.file.split(\".\")[0];\n\t\t\t\tconst url = `${this.url}sounds/${sound.file}?v=${sound.version || 0}`;\n\n\t\t\t\ttry {\n\t\t\t\t\t// Sound class handles loading via XMLHttpRequest and AudioBuffer internally.\n\t\t\t\t\t// Resolve immediately — readiness is polled via isReady()/getProgress() in the game loop.\n\t\t\t\t\tconst soundInstance = new Sound(this.audioCore, url);\n\t\t\t\t\tthis.collections.sounds[name] = soundInstance;\n\t\t\t\t\tresolve();\n\t\t\t\t} catch (err) {\n\t\t\t\t\tthis.listener?.log?.(`[AssetLoader] Failed to load sound \"${name}\": ${String(err)}`);\n\t\t\t\t\tthis.collections.sounds[name] = new Sound(this.audioCore, url);\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\tawait Promise.all(promises);\n\t}\n\n\t/**\n\t * Load music\n\t */\n\tprivate async loadMusic(): Promise<void> {\n\t\tif (!this.resources.music) return;\n\n\t\tconst promises = this.resources.music.map((mus) => {\n\t\t\treturn new Promise<void>((resolve) => {\n\t\t\t\tconst name = mus.file.split(\".\")[0];\n\t\t\t\tconst url = `${this.url}music/${mus.file}?v=${mus.version || 0}`;\n\n\t\t\t\ttry {\n\t\t\t\t\t// Music class handles HTML5 Audio internally (streaming — ready immediately).\n\t\t\t\t\tconst musicInstance = new Music(this.audioCore, url);\n\t\t\t\t\tthis.collections.music[name] = musicInstance;\n\t\t\t\t\tresolve();\n\t\t\t\t} catch (err) {\n\t\t\t\t\tthis.listener?.log?.(`[AssetLoader] Failed to load music \"${name}\": ${String(err)}`);\n\t\t\t\t\tthis.collections.music[name] = new Music(this.audioCore, url);\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\tawait Promise.all(promises);\n\t}\n\n\t/**\n\t * Load generic assets\n\t */\n\tprivate async loadGenericAssets(): Promise<void> {\n\t\tif (!this.resources.assets) return;\n\n\t\tfor (const asset of this.resources.assets) {\n\t\t\tconst name = asset.file.split(\".\")[0].replace(/-/g, \"/\");\n\t\t\tthis.collections.assets[name] = {\n\t\t\t\tname,\n\t\t\t\tfile: asset.file,\n\t\t\t\tversion: asset.version,\n\t\t\t};\n\t\t}\n\t}\n\n\t/**\n\t * Check if all assets are ready\n\t */\n\tisReady(): boolean {\n\t\treturn this.countReady() === this.countTotal();\n\t}\n\n\t/**\n\t * Get loading progress (0-1)\n\t */\n\tgetProgress(): number {\n\t\tconst total = this.countTotal();\n\t\tif (total === 0) return 1;\n\t\treturn this.countReady() / total;\n\t}\n\n\t/**\n\t * Count total assets\n\t */\n\tprivate countTotal(): number {\n\t\tlet count = 0;\n\t\tcount += Object.keys(this.collections.sprites).length;\n\t\tcount += Object.keys(this.collections.maps).length;\n\t\tcount += Object.keys(this.collections.sounds).length;\n\t\tcount += Object.keys(this.collections.music).length;\n\t\treturn count;\n\t}\n\n\t/**\n\t * Count ready assets\n\t */\n\tprivate countReady(): number {\n\t\tlet ready = 0;\n\n\t\tfor (const sprite of Object.values(this.collections.sprites)) {\n\t\t\tif (sprite.ready) ready++;\n\t\t}\n\t\tfor (const map of Object.values(this.collections.maps)) {\n\t\t\tif (map.ready) ready++;\n\t\t}\n\t\tfor (const sound of Object.values(this.collections.sounds)) {\n\t\t\tif (sound.ready) ready++;\n\t\t}\n\t\tfor (const mus of Object.values(this.collections.music)) {\n\t\t\tif (mus.ready) ready++;\n\t\t}\n\n\t\treturn ready;\n\t}\n\n\t/**\n\t * Show loading bar on screen\n\t */\n\tshowLoadingBar(screenInterface: any): void {\n\t\t// Throttle redraws\n\t\tif (this.loadingBarTime && Date.now() < this.loadingBarTime + LOADING_BAR_THROTTLE_MS) {\n\t\t\treturn;\n\t\t}\n\t\tthis.loadingBarTime = Date.now();\n\n\t\tconst progress = this.getProgress();\n\t\tscreenInterface.clear(\"#000\");\n\t\tscreenInterface.drawRect(0, 0, 100, 10, \"#DDD\");\n\t\tscreenInterface.fillRect(-(1 - progress) * 48, 0, progress * 96, 6, \"#DDD\");\n\t}\n\n\t/**\n\t * Get loaded collections\n\t */\n\tgetCollections(): AssetCollections {\n\t\treturn this.collections;\n\t}\n}\n","/** Default frames per second */\nexport const DEFAULT_FPS = 60;\n\n/** Default update rate (updates per second) */\nexport const DEFAULT_UPDATE_RATE = 60;\n\n/** Frame time in milliseconds at 60 FPS */\nexport const FRAME_TIME_MS = 1000 / DEFAULT_FPS;\n\n/** Threshold in ms to detect long pauses (tab switch, etc.) */\nexport const PAUSE_THRESHOLD_MS = 160;\n\n/** Default tile/block size in pixels */\nexport const DEFAULT_BLOCK_SIZE = 16;\n\n/** Minimum interval between loading bar redraws in ms (~60fps) */\nexport const LOADING_BAR_THROTTLE_MS = 16;\n\n/** Timeout in ms for individual asset loads (sprite/map HTTP requests) */\nexport const ASSET_LOAD_TIMEOUT_MS = 30_000;\n"],"mappings":"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","names":["import_audio","DEFAULT_FPS","FRAME_TIME_MS","DEFAULT_FPS","DEFAULT_BLOCK_SIZE","LOADING_BAR_THROTTLE_MS","ASSET_LOAD_TIMEOUT_MS","import_map","import_sprites","withTimeout","promise","ms","Promise","race","_","reject","setTimeout","Error","AssetLoader","url","resources","collections","loadingBarTime","audioCore","listener","sprites","maps","sounds","music","assets","loadAll","all","loadSprites","loadMaps","loadSounds","loadMusic","loadGenericAssets","loadCallbackAssets","urlPrefix","collectionKey","load","createPlaceholder","promises","map","res","resolve","name","file","split","replace","version","inner","onReady","ASSET_LOAD_TIMEOUT_MS","then","catch","err","log","slice","String","images","img","LoadSprite","properties","ready","frames","fps","width","height","_mapRes","LoadMap","block_width","DEFAULT_BLOCK_SIZE","block_height","data","sound","soundInstance","Sound","mus","musicInstance","Music","asset","isReady","countReady","countTotal","getProgress","total","count","Object","keys","length","sprite","values","showLoadingBar","screenInterface","Date","now","LOADING_BAR_THROTTLE_MS","progress","clear","drawRect","fillRect","getCollections"]}