@moku-labs/game 0.0.1 → 0.0.2

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