@moku-labs/game 0.2.0 → 0.4.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 (35) hide show
  1. package/README.md +2 -0
  2. package/dist/assets.d.mts +181 -22
  3. package/dist/assets.mjs +1186 -160
  4. package/dist/{commands-C0BljsM5.d.mts → commands-DYO22lzi.d.mts} +22 -5
  5. package/dist/control.d.mts +3 -3
  6. package/dist/control.mjs +3 -3
  7. package/dist/{define-CjP_4H0G.d.mts → define-BKWjWgyQ.d.mts} +1 -1
  8. package/dist/dev-CQYJPmcD.mjs +1183 -0
  9. package/dist/flatten-BkXuscAV.mjs +100 -0
  10. package/dist/index.d.mts +85 -31
  11. package/dist/index.mjs +3208 -490
  12. package/dist/{session-DmAxY6Ll.mjs → input-CK4nxBO1.mjs} +41 -12
  13. package/dist/inspect.d.mts +32 -9
  14. package/dist/inspect.mjs +2 -2
  15. package/dist/jsx-dev-runtime.d.mts +1 -1
  16. package/dist/jsx-dev-runtime.mjs +1 -1
  17. package/dist/jsx-runtime.d.mts +1 -1
  18. package/dist/jsx-runtime.mjs +1 -1
  19. package/dist/{run-tlcn1w7y.mjs → run-BfuMLahc.mjs} +489 -213
  20. package/dist/{runtime-Bn5TXNxP.d.mts → runtime-Bhu442L8.d.mts} +1 -1
  21. package/dist/{runtime-DRlwxkIv.mjs → runtime-CBZgWgzx.mjs} +1 -57
  22. package/dist/{sources-BooL2MsX.mjs → sources-C1uGjz4l.mjs} +198 -21
  23. package/dist/testing.d.mts +5 -5
  24. package/dist/testing.mjs +5 -4
  25. package/dist/{types-CxZy7Pi4.d.mts → types-BnWH-75b.d.mts} +95 -21
  26. package/dist/{types-CqkrEY06.d.mts → types-CVUHPvMB.d.mts} +5 -434
  27. package/dist/{types-DmhTHRVW.d.mts → types-DtmFVCHf.d.mts} +1 -1
  28. package/dist/{types-BZ1OLf24.d.mts → types-Dy1xB68L.d.mts} +2318 -1169
  29. package/dist/{types-X9jXjka3.d.mts → types-VErbiEXy.d.mts} +867 -198
  30. package/dist/{visual-NPrDkvUk.mjs → visual-DUvvPPCt.mjs} +51 -1
  31. package/llms.txt +5 -5
  32. package/package.json +5 -5
  33. package/dist/component-DGg5DqKK.mjs +0 -44
  34. package/dist/dev-CcwFrwok.mjs +0 -413
  35. package/dist/types-C47fKNcn.d.mts +0 -695
@@ -1,695 +0,0 @@
1
- import { St as Api$3, f as SliceFrame, mt as NodeInfo, nn as Require, o as PixiTexture, q as Api$1, t as Api$2, vt as Descriptor } from "./types-BZ1OLf24.mjs";
2
- import { Log } from "@moku-labs/common/browser";
3
- import { PluginCtx } from "@moku-labs/core";
4
-
5
- //#region src/plugins/assets/types.d.ts
6
- declare namespace types_d_exports {
7
- export { Api, AssetKind, AssetsCtx, AssetsIo, AtlasFrame, AtlasPage, BundleMap, BundleRecord, BundleSpec, BundleUsage, Config, CreateTextureOptions, DecodedImage, DefineBundles, Deps, Events, FetchResponse, FlowRest, FontAsset, FontPage, Inflight, KernelSlice, LoadBundles, LoadReason, LoadResult, LoadedAssets, LoadedFont, Manifest, ManifestBundle, ManifestFile, NineBorders, NineSlice, PreloadQueue, State, Texture, Tier, Usage };
8
- }
9
- /**
10
- * When a bundle is loaded. `boot` and `core` stay for the whole session, `scene` and `feature`
11
- * come and go with the graph, `lazy` is never preloaded.
12
- *
13
- * @example
14
- * ```ts
15
- * const tier: Tier = "scene";
16
- * ```
17
- */
18
- type Tier = "boot" | "core" | "scene" | "feature" | "lazy";
19
- /**
20
- * What one file of a bundle is. A `.fnt` with its `.png` pages is one `font`, an `.mp3` is
21
- * `audio`, everything else is a `texture`. A file of an older manifest that names no kind is a
22
- * texture.
23
- *
24
- * @example
25
- * ```ts
26
- * const kind: AssetKind = "font";
27
- * ```
28
- */
29
- type AssetKind = "texture" | "font" | "audio";
30
- /**
31
- * A GPU texture. `assets` owns its lifetime and never imports Pixi: `renderer` makes and destroys
32
- * it, this plugin only says when.
33
- */
34
- type Texture = PixiTexture;
35
- /**
36
- * A decoded image, ready for the upload. `createImageBitmap` produces the first shape.
37
- */
38
- type DecodedImage = ImageBitmap | HTMLImageElement;
39
- /**
40
- * Nine-slice borders in pixels, in the order left, top, right, bottom.
41
- *
42
- * @example
43
- * ```ts
44
- * const borders: NineBorders = [48, 48, 48, 48];
45
- * ```
46
- */
47
- type NineBorders = readonly [number, number, number, number];
48
- /**
49
- * Options of `io.createTexture`. Same shape as `renderer.sync.textures.create`.
50
- *
51
- * @example
52
- * ```ts
53
- * const options: CreateTextureOptions = { nine: [48, 48, 48, 48] };
54
- * ```
55
- */
56
- type CreateTextureOptions = {
57
- nine?: NineBorders;
58
- };
59
- /**
60
- * The part of a fetch response the plugin reads: the manifest is `json`, a texture is a `blob`,
61
- * a font file is `text` and an audio file stays the raw `arrayBuffer`. The global `Response`
62
- * fits it. `headers` gives the `content-type`: on `tauri://` a missing file comes back `200` with
63
- * `index.html`, so `text/html` for a path that is not `.html` counts as missing.
64
- */
65
- type FetchResponse = {
66
- ok: boolean;
67
- status: number;
68
- headers: {
69
- get(name: string): string | null;
70
- };
71
- json(): Promise<unknown>;
72
- blob(): Promise<Blob>;
73
- text(): Promise<string>;
74
- arrayBuffer(): Promise<ArrayBuffer>;
75
- };
76
- /**
77
- * The I/O seam: everything that leaves the plugin. `undefined` in the config means the browser
78
- * pair plus `renderer.sync.textures`; a test passes a fake and nothing touches the network or a GPU.
79
- *
80
- * @example
81
- * ```ts
82
- * // A unit test serves two files from memory and counts the textures it handed out.
83
- * const io: AssetsIo = {
84
- * fetch: async () => ({
85
- * ok: true,
86
- * status: 200,
87
- * headers: { get: () => null },
88
- * json: async () => ({}),
89
- * blob: async () => blob,
90
- * text: async () => 'info face="body"',
91
- * arrayBuffer: async () => new ArrayBuffer(8)
92
- * }),
93
- * decode: async () => bitmap,
94
- * createTexture: () => ({ id: "t1" }) as unknown as Texture,
95
- * sliceTexture: (page, frame) => ({ id: "s1", page, frame }) as unknown as Texture,
96
- * destroyTexture: texture => destroyed.push(texture)
97
- * };
98
- *
99
- * createApp({ plugins: [...screen], pluginConfigs: { assets: { io, manifest } } });
100
- * ```
101
- */
102
- type AssetsIo = {
103
- /**
104
- * Fetches one URL: the manifest, or a file of a bundle.
105
- *
106
- * @param url - Absolute or root-relative URL.
107
- * @param init - Carries the abort signal of the running load.
108
- * @param init.signal - Aborts the request when the load is cancelled.
109
- * @returns The response.
110
- */
111
- fetch(url: string, init: {
112
- signal: AbortSignal;
113
- }): Promise<FetchResponse>;
114
- /**
115
- * Decodes one image file.
116
- *
117
- * @param blob - The bytes of the file.
118
- * @returns The decoded image.
119
- */
120
- decode(blob: Blob): Promise<DecodedImage>;
121
- /**
122
- * Uploads one decoded image to the GPU.
123
- *
124
- * @param image - The decoded image.
125
- * @param options - `nine` becomes the default nine-slice borders of the texture.
126
- * @returns The new texture.
127
- */
128
- createTexture(image: DecodedImage, options?: CreateTextureOptions): Texture;
129
- /**
130
- * Cuts the texture of one packed file out of its atlas page. The slice shares the page's
131
- * source: no pixel is copied. Same shape as `renderer.sync.textures.slice`; the manifest's
132
- * `atlas` frame is passed as it is.
133
- *
134
- * @param page - The page texture, made by `createTexture`.
135
- * @param frame - Where the file lies on the page, in page pixels.
136
- * @param options - `nine` becomes the default nine-slice borders of the slice.
137
- * @returns The new texture over the page's source.
138
- */
139
- sliceTexture(page: Texture, frame: SliceFrame, options?: CreateTextureOptions): Texture;
140
- /**
141
- * Frees one texture. A page frees its source too; a slice frees only itself, so the slices of
142
- * a bundle go first and its pages after them.
143
- *
144
- * @param texture - The texture to free.
145
- */
146
- destroyTexture(texture: Texture): void;
147
- };
148
- /**
149
- * Nine-slice metadata of one file, as the scanner writes it. Always four numbers: the tags
150
- * `{nine=N}`, `{nine=H,V}` and `{nine=L,T,R,B}` all land here.
151
- *
152
- * @example
153
- * ```ts
154
- * const nine: NineSlice = { left: 48, top: 48, right: 48, bottom: 48 };
155
- * ```
156
- */
157
- type NineSlice = {
158
- left: number;
159
- top: number;
160
- right: number;
161
- bottom: number;
162
- };
163
- /**
164
- * Where a packed file lies: `page` is the id of a page of the same bundle, never a file name, and
165
- * the frame is in page pixels. `width` and `height` equal the file's own, so its `nine` stays
166
- * valid as it is. The packer writes it; the loader cuts the file out of the page.
167
- *
168
- * @example
169
- * ```ts
170
- * const frame: AtlasFrame = { page: "ui/main-0", x: 583, y: 595, width: 256, height: 128 };
171
- * ```
172
- */
173
- type AtlasFrame = {
174
- page: string;
175
- x: number;
176
- y: number;
177
- width: number;
178
- height: number;
179
- };
180
- /**
181
- * One atlas page of a packed bundle. `id` is `<bundle>/<group>-<index>`, the name an `atlas`
182
- * frame uses; `path` is the hashed WebP file, read like the `path` of a file. `mb` is
183
- * `width × height × 4 / 1 048 576`: the page carries the cost of every file packed on it.
184
- *
185
- * @example
186
- * ```ts
187
- * const page: AtlasPage = {
188
- * id: "ui/main-0",
189
- * path: "ui/main-0-3b1d55a0c9.webp",
190
- * width: 966,
191
- * height: 1365,
192
- * mb: 5.03
193
- * };
194
- * ```
195
- */
196
- type AtlasPage = {
197
- id: string;
198
- path: string;
199
- width: number;
200
- height: number;
201
- mb: number;
202
- };
203
- /**
204
- * One page image of a font. A page has no key of its own: it belongs to the `.fnt` file that
205
- * names it, and is loaded and freed with it.
206
- *
207
- * @example
208
- * ```ts
209
- * const page: FontPage = {
210
- * path: "features/ui/assets/body_0.png",
211
- * width: 256,
212
- * height: 128,
213
- * mb: 0.125
214
- * };
215
- * ```
216
- */
217
- type FontPage = {
218
- path: string;
219
- width: number;
220
- height: number;
221
- mb: number;
222
- };
223
- /**
224
- * One file of a bundle. `mb` is what it costs: `width × height × 4` bytes for a texture, the sum
225
- * of the pages for a font, the size of the file for audio, and `0` for a texture packed in an
226
- * atlas, whose page carries the cost. `kind` is absent for a texture, which is what every
227
- * manifest written before fonts and audio carries. A loose file has `path`; a packed texture has
228
- * `atlas` and no `path`.
229
- *
230
- * @example
231
- * ```ts
232
- * // The dev manifest of the scanner: a loose file.
233
- * const loose: ManifestFile = {
234
- * key: "ui.panel",
235
- * path: "features/ui/assets/panel{nine=48}.png",
236
- * width: 256,
237
- * height: 128,
238
- * mb: 0.125,
239
- * nine: { left: 48, top: 48, right: 48, bottom: 48 }
240
- * };
241
- *
242
- * // The packed manifest: the same key, cut out of the page "ui/main-0".
243
- * const packed: ManifestFile = {
244
- * key: "ui.panel",
245
- * width: 256,
246
- * height: 128,
247
- * mb: 0,
248
- * nine: { left: 48, top: 48, right: 48, bottom: 48 },
249
- * atlas: { page: "ui/main-0", x: 583, y: 595, width: 256, height: 128 }
250
- * };
251
- * ```
252
- */
253
- type ManifestFile = {
254
- key: string;
255
- path?: string;
256
- kind?: AssetKind;
257
- width: number;
258
- height: number;
259
- mb: number;
260
- pages?: readonly FontPage[];
261
- nine?: NineSlice;
262
- atlas?: AtlasFrame;
263
- };
264
- /**
265
- * One bundle of the manifest: which feature owns it, when it loads and what it costs. `pages` is
266
- * written by the packer only, sorted by id; `mb` is then its pages, its loose textures, its font
267
- * pages and its audio bytes together.
268
- *
269
- * @example
270
- * ```ts
271
- * const bundle: ManifestBundle = { feature: "ui", tier: "core", mb: 0.125, files: [] };
272
- * ```
273
- */
274
- type ManifestBundle = {
275
- feature: string;
276
- tier: Tier;
277
- mb: number;
278
- pages?: readonly AtlasPage[];
279
- files: readonly ManifestFile[];
280
- };
281
- /**
282
- * The manifest: the contract between the scanner, the packer, this plugin and the editor. Version
283
- * `1` is the dev manifest of `bun run assets:keys`, version `2` the packed one of
284
- * `bun run assets:pack`; the plugin reads both. Bundles are sorted by name, pages by id and files
285
- * by key, so two runs on the same tree give the same bytes.
286
- *
287
- * @example
288
- * ```ts
289
- * // A dev build: loose files, straight from the features.
290
- * const manifest: Manifest = {
291
- * version: 1,
292
- * bundles: { ui: { feature: "ui", tier: "core", mb: 0, files: [] } }
293
- * };
294
- *
295
- * createApp({ plugins: [...screen], pluginConfigs: { assets: { manifest } } });
296
- *
297
- * // The packed manifest of the same game: the panel is cut out of the page "ui/main-0".
298
- * const page = { id: "ui/main-0", path: "ui/main-0-3b1d55a0c9.webp", width: 966, height: 1365, mb: 5.03 };
299
- * const atlas = { page: "ui/main-0", x: 583, y: 595, width: 256, height: 128 };
300
- * const panel = { key: "ui.panel", width: 256, height: 128, mb: 0, atlas };
301
- * const packed: Manifest = {
302
- * version: 2,
303
- * bundles: { ui: { feature: "ui", tier: "core", mb: 5.03, pages: [page], files: [panel] } }
304
- * };
305
- * ```
306
- */
307
- type Manifest = {
308
- version: 1 | 2;
309
- bundles: Readonly<Record<string, ManifestBundle>>;
310
- };
311
- /**
312
- * What a feature declares about one of its bundles. `files` are globs relative to the feature's
313
- * `assets/`; a bundle with `files` takes those files out of the feature's default bundle.
314
- *
315
- * @example
316
- * ```ts
317
- * const spec: BundleSpec = { tier: "lazy", files: ["chains/*.png"] };
318
- * ```
319
- */
320
- type BundleSpec = {
321
- tier: Tier;
322
- files?: readonly string[];
323
- };
324
- /**
325
- * What `defineBundles` returns: plain data the scanner and the plugin both read.
326
- *
327
- * @example
328
- * ```ts
329
- * const bundles: BundleMap = {
330
- * kind: "bundles",
331
- * map: { board: { tier: "scene" }, "board.chains": { tier: "lazy", files: ["chains/*.png"] } }
332
- * };
333
- * ```
334
- */
335
- type BundleMap<Key extends string = string> = {
336
- kind: "bundles";
337
- map: Partial<Record<Key, BundleSpec>>;
338
- };
339
- /**
340
- * `defineBundles` bound to the bundle keys of one game. `defineGame` returns it, so a key that is
341
- * not in `BundleKey` does not compile.
342
- *
343
- * @example
344
- * ```ts
345
- * const defineGameBundles: DefineBundles<"board" | "board.chains"> = defineBundles;
346
- * ```
347
- */
348
- type DefineBundles<Key extends string> = (map: Partial<Record<Key, BundleSpec>>) => BundleMap<Key>;
349
- /**
350
- * The `load` descriptor helper bound to the bundle keys of one game.
351
- *
352
- * @example
353
- * ```ts
354
- * const loadGameBundle: LoadBundles<"board" | "board.chains"> = load;
355
- * ```
356
- */
357
- type LoadBundles<Key extends string> = (bundle: Key | readonly Key[]) => Descriptor;
358
- /**
359
- * What the `load` effect resolves with, so a loading node can write its own progress.
360
- *
361
- * @example
362
- * ```ts
363
- * const result: LoadResult = { loaded: ["board.chains"], mb: 1.25 };
364
- * ```
365
- */
366
- type LoadResult = {
367
- loaded: string[];
368
- mb: number;
369
- };
370
- /**
371
- * Why a bundle was loaded. It is the reason of the caller that started the load; a later waiter
372
- * changes nothing.
373
- *
374
- * @example
375
- * ```ts
376
- * const reason: LoadReason = "enter";
377
- * ```
378
- */
379
- type LoadReason = "boot" | "enter" | "request" | "preload";
380
- /**
381
- * The running load of one bundle. Every caller is a waiter; the last one to leave aborts it.
382
- * `promise` never rejects: what broke waits in `error`, so a load nobody joined any more cannot
383
- * become an unhandled rejection.
384
- */
385
- type Inflight = {
386
- promise: Promise<void>;
387
- controller: AbortController;
388
- waiters: number;
389
- error: unknown;
390
- };
391
- /**
392
- * A loaded font: the `.fnt` file as text and the page textures it names. `text` installs the
393
- * first page in the renderer; every page is destroyed with the bundle.
394
- *
395
- * @example
396
- * ```ts
397
- * const font: FontAsset = { fnt: 'info face="body" size=32', texture };
398
- * ```
399
- */
400
- type FontAsset = {
401
- fnt: string;
402
- texture: Texture;
403
- };
404
- /**
405
- * What the plugin keeps for a loaded font: the public pair plus every page, because a font of
406
- * two pages owns two textures.
407
- */
408
- type LoadedFont = FontAsset & {
409
- pages: readonly Texture[];
410
- };
411
- /**
412
- * What one bundle brought: textures by asset key (a packed file's is a slice of its page), fonts
413
- * with their pages, the undecoded bytes of the audio files, and the atlas pages by page id. A
414
- * running load fills the same four maps before they are published.
415
- */
416
- type LoadedAssets = {
417
- textures: Map<string, Texture>;
418
- fonts: Map<string, LoadedFont>;
419
- audio: Map<string, ArrayBuffer>;
420
- pages: Map<string, Texture>;
421
- };
422
- /**
423
- * What the plugin knows about one bundle. `lastUsed` is the value of `useCounter` at the last
424
- * touch: a counter, never a clock.
425
- */
426
- type BundleRecord = LoadedAssets & {
427
- status: "idle" | "loading" | "loaded";
428
- inflight: Inflight | undefined;
429
- lastUsed: number;
430
- };
431
- /**
432
- * The background preload. A new rest node replaces it and aborts the old controller.
433
- */
434
- type PreloadQueue = {
435
- bundles: string[];
436
- controller: AbortController;
437
- };
438
- /**
439
- * assets plugin config.
440
- *
441
- * @example
442
- * ```ts
443
- * createApp({
444
- * plugins: [...screen, boardFeature],
445
- * pluginConfigs: { assets: { manifest: "/assets/manifest.json", textureBudgetMb: 192 } }
446
- * });
447
- * ```
448
- */
449
- type Config = {
450
- /** URL of `manifest.json`, or the parsed manifest itself (tests, headless). `undefined`: an empty manifest. */manifest: string | Manifest | undefined; /** Texture memory budget in MB. */
451
- textureBudgetMb: number; /** How many edges from a rest node the background preload looks ahead. `0` turns preload off. */
452
- preloadDepth: number; /** Prefix of every file URL. The CDN seam. `undefined`: the folder of the manifest URL, or `"/"`. */
453
- baseUrl: string | undefined; /** I/O seam. `undefined`: the browser pair plus `renderer.sync.textures`, or headless. */
454
- io: AssetsIo | undefined;
455
- };
456
- /**
457
- * assets plugin state.
458
- */
459
- type State = {
460
- /** `undefined` means headless: manifest only, no fetches, no textures. */io: AssetsIo | undefined; /** Empty until `onStart` read it. */
461
- manifest: Manifest; /** Asset key to the bundle that carries it. */
462
- bundleOfKey: Map<string, string>; /** Scene id to its bundle, read from the `scenes` key of `flow.features`. */
463
- bundleOfScene: Map<string, string>; /** Flow id to the feature that owns it, read from the `flows` key of `flow.features`. */
464
- featureOfFlow: Map<string, string>;
465
- records: Map<string, BundleRecord>; /** Bundles of the node entered last. They are never unloaded. */
466
- pinned: Set<string>; /** The bundle of the scene entered last. A node without `scene` keeps it. */
467
- sceneBundle: string | undefined;
468
- queue: PreloadQueue | undefined;
469
- current: NodeInfo | undefined;
470
- useCounter: number; /** Keys already reported missing, so one key warns and starts its background load once. */
471
- warned: Set<string>; /** `onEnter`, the `load` handler and the texture provider. */
472
- removers: Array<() => void>;
473
- };
474
- /**
475
- * What `usage()` reports about one loaded bundle.
476
- *
477
- * @example
478
- * ```ts
479
- * const entry: BundleUsage = { name: "board", tier: "scene", mb: 3.5, lastUsed: 12 };
480
- * ```
481
- */
482
- type BundleUsage = {
483
- name: string;
484
- tier: Tier;
485
- mb: number;
486
- lastUsed: number;
487
- };
488
- /**
489
- * What `usage()` reports: the numbers a dev overlay and the tests read.
490
- *
491
- * @example
492
- * ```ts
493
- * const report: Usage = { textureMb: 3.5, budgetMb: 192, bundles: [] };
494
- * ```
495
- */
496
- type Usage = {
497
- textureMb: number;
498
- budgetMb: number;
499
- bundles: readonly BundleUsage[];
500
- };
501
- /**
502
- * assets plugin events.
503
- *
504
- * @example
505
- * ```ts
506
- * // A game reports every loaded bundle to its analytics.
507
- * createPlugin("loadReport", {
508
- * depends: [assetsPlugin],
509
- * hooks: ctx => ({ "assets:bundle-loaded": ({ bundle, mb }) => ctx.log.info("loaded", { bundle, mb }) })
510
- * }); // the board bundle logs { bundle: "board", mb: 3.5 }
511
- *
512
- * // A splash screen fills its loading bar file by file.
513
- * createPlugin("loadingBar", {
514
- * depends: [assetsPlugin],
515
- * createState: () => ({ share: 0 }),
516
- * hooks: ctx => ({
517
- * "assets:bundle-progress": ({ loaded, total }) => {
518
- * ctx.state.share = loaded / total;
519
- * }
520
- * })
521
- * }); // a board bundle of four files sets share to 0.25, 0.5, 0.75 and 1; bundle-loaded follows
522
- * ```
523
- */
524
- type Events = {
525
- /** Every file of a bundle is a texture now. */"assets:bundle-loaded": {
526
- bundle: string;
527
- tier: Tier;
528
- mb: number;
529
- reason: LoadReason;
530
- };
531
- /**
532
- * One more file of a running load settled. `loaded` counts the settled files (a font once, with
533
- * its pages), `total` is the file count of the bundle; the last one of a load has
534
- * `loaded === total` and comes before `assets:bundle-loaded`. An aborted load sends none.
535
- */
536
- "assets:bundle-progress": {
537
- bundle: string;
538
- loaded: number;
539
- total: number;
540
- }; /** The textures of a bundle were destroyed. `keys` names every asset that went with it. */
541
- "assets:bundle-unloaded": {
542
- bundle: string;
543
- tier: Tier;
544
- mb: number;
545
- reason: "budget" | "request";
546
- keys: readonly string[];
547
- };
548
- };
549
- /**
550
- * assets plugin API, `app.assets`. Bundles of textures by key: the graph decides when they arrive,
551
- * the budget decides when they leave.
552
- *
553
- * @example
554
- * ```ts
555
- * // A loading node asks for a bundle and a game system asks for one texture of it.
556
- * await app.assets.load("board");
557
- * app.assets.texture("board.cell"); // the Pixi texture, once the bundle is there
558
- * ```
559
- */
560
- type Api = {
561
- /**
562
- * Loads every file of a bundle. An already loaded bundle resolves at once, a loading one joins
563
- * the running load. Headless it resolves at once and touches nothing.
564
- *
565
- * @param bundle - Name of a bundle of the manifest.
566
- * @returns A promise that resolves when every texture of the bundle exists.
567
- * @throws {Error} When the manifest has no such bundle, and when a file fails to load.
568
- * @example
569
- * ```ts
570
- * // A game plugin warms the bundle of a timed event before its popup can open.
571
- * await app.assets.load("event.halloween");
572
- * app.assets.isLoaded("event.halloween"); // true
573
- * ```
574
- */
575
- load(bundle: string): Promise<void>;
576
- /**
577
- * Destroys the textures of a bundle and tells `renderer` that its keys are gone. A pinned
578
- * bundle and the tiers `boot` and `core` are refused with a warning. A running load is aborted.
579
- *
580
- * @param bundle - Name of a loaded bundle.
581
- * @example
582
- * ```ts
583
- * // The timed event ended: its textures go back to the GPU.
584
- * app.assets.unload("event.halloween");
585
- * app.assets.isLoaded("event.halloween"); // false
586
- * ```
587
- */
588
- unload(bundle: string): void;
589
- /**
590
- * Tells whether every texture of a bundle exists. Headless every bundle of the manifest counts
591
- * as loaded, so a headless game never waits for a loading screen.
592
- *
593
- * @param bundle - Name of a bundle of the manifest.
594
- * @returns True when the bundle is loaded.
595
- * @example
596
- * ```ts
597
- * // `scenes` skips its loading path when the bundle of the next scene is already there.
598
- * if (!app.assets.isLoaded("board")) await app.assets.load("board");
599
- * ```
600
- */
601
- isLoaded(bundle: string): boolean;
602
- /**
603
- * The texture of a loaded asset key. It touches the use counter of the bundle, which is what
604
- * the LRU reads. A key of a bundle that is not loaded warns once, starts a background load and
605
- * answers `undefined`; the sprites waiting for it are textured when that load lands. A key packed
606
- * in an atlas answers its slice of the page, so a game never sees the difference.
607
- *
608
- * @param key - Asset key, as `generated/assets.ts` types it.
609
- * @returns The texture, or `undefined` while the bundle is not loaded.
610
- * @example
611
- * ```ts
612
- * // A game system builds one Pixi object by hand instead of using the Sprite component.
613
- * const texture = app.assets.texture("board.cell"); // undefined until the board bundle lands
614
- * ```
615
- */
616
- texture(key: string): Texture | undefined;
617
- /**
618
- * The font of a loaded asset key: the `.fnt` file as text and the texture of its first page.
619
- * It touches the use counter of the bundle. A font of a bundle that is not loaded, a key of
620
- * another kind and every headless run answer `undefined`.
621
- *
622
- * @param key - Asset key of a `.fnt` file, as `generated/assets.ts` types it in `FontKey`.
623
- * @returns The font, or `undefined` while its bundle is not loaded.
624
- * @example
625
- * ```ts
626
- * // `text` installs the font in the renderer when the bundle that carries it arrived.
627
- * const font = app.assets.font("ui.body"); // { fnt: 'info face="body" size=32', texture }
628
- *
629
- * if (font !== undefined) app.renderer.sync.fonts.install("ui.body", font.fnt, font.texture);
630
- * ```
631
- */
632
- font(key: string): FontAsset | undefined;
633
- /**
634
- * The bytes of a loaded audio file, exactly as they were fetched: this plugin never decodes
635
- * them. It touches the use counter of the bundle. A bundle that is not loaded, a key of
636
- * another kind and every headless run answer `undefined`.
637
- *
638
- * @param key - Asset key of an `.mp3` file, as `generated/assets.ts` types it in `AudioKey`.
639
- * @returns The undecoded bytes, or `undefined` while its bundle is not loaded.
640
- * @example
641
- * ```ts
642
- * // `audio` decodes a sound once and keeps it until the bundle is unloaded.
643
- * const bytes = app.assets.audio("ui.click"); // the ArrayBuffer of click.mp3
644
- * const buffer = bytes === undefined ? undefined : await context.decodeAudioData(bytes);
645
- * ```
646
- */
647
- audio(key: string): ArrayBuffer | undefined;
648
- /**
649
- * What the loaded bundles cost, sorted by name. `lastUsed` is the use counter, not a clock.
650
- *
651
- * @returns The used and allowed megabytes and one entry per loaded bundle.
652
- * @example
653
- * ```ts
654
- * // A dev overlay draws the memory bar of the game.
655
- * const { textureMb, budgetMb, bundles } = app.assets.usage();
656
- * // textureMb: 3.5, budgetMb: 192, bundles: [{ name: "board", tier: "scene", mb: 3.5, lastUsed: 12 }]
657
- * ```
658
- */
659
- usage(): Usage;
660
- };
661
- /**
662
- * Resolved dependency APIs.
663
- */
664
- type Deps = {
665
- flow: Api$1;
666
- renderer: Api$2;
667
- time: Api$3;
668
- };
669
- /**
670
- * What the kernel context offers before the deps are attached.
671
- *
672
- * `index.ts` writes `events` with an annotated `register` (core spec `14-EVENT-REGISTRATION.md`
673
- * row 8), so the two own events reach the context the kernel hands the factories and `emit` is the
674
- * kernel's own, assets-typed one. No member of the context is cast.
675
- */
676
- type KernelSlice = PluginCtx<Config, State, Events> & {
677
- readonly global: object;
678
- readonly log: Log.LogApi;
679
- readonly require: Require;
680
- };
681
- /**
682
- * Domain context shared by the files of the plugin.
683
- */
684
- type AssetsCtx = KernelSlice & {
685
- readonly deps: Deps;
686
- };
687
- /**
688
- * Payload of the one event assets listens to.
689
- */
690
- type FlowRest = {
691
- path: string;
692
- checkpoint: boolean;
693
- };
694
- //#endregion
695
- export { DefineBundles as a, LoadReason as c, Tier as d, Usage as f, Config as i, Manifest as l, BundleMap as n, Events as o, types_d_exports as p, BundleSpec as r, LoadBundles as s, Api as t, State as u };