ecspresso 0.10.2 → 0.11.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 (82) hide show
  1. package/README.md +73 -17
  2. package/dist/asset-manager.d.ts +15 -15
  3. package/dist/asset-types.d.ts +16 -14
  4. package/dist/bundle.d.ts +66 -16
  5. package/dist/bundles/audio.d.ts +293 -0
  6. package/dist/bundles/{utils/bounds.d.ts → bounds.d.ts} +9 -7
  7. package/dist/bundles/camera.d.ts +89 -0
  8. package/dist/bundles/collision.d.ts +289 -0
  9. package/dist/bundles/diagnostics.d.ts +48 -0
  10. package/dist/bundles/{utils/input.d.ts → input.d.ts} +16 -17
  11. package/dist/bundles/physics2D.d.ts +159 -0
  12. package/dist/bundles/renderers/renderer2D.d.ts +65 -24
  13. package/dist/bundles/spatial-index.d.ts +57 -0
  14. package/dist/bundles/state-machine.d.ts +298 -0
  15. package/dist/bundles/{utils/timers.d.ts → timers.d.ts} +9 -8
  16. package/dist/bundles/{utils/transform.d.ts → transform.d.ts} +10 -10
  17. package/dist/bundles/tween.d.ts +197 -0
  18. package/dist/command-buffer.d.ts +20 -20
  19. package/dist/ecspresso-builder.d.ts +165 -0
  20. package/dist/ecspresso.d.ts +157 -178
  21. package/dist/entity-manager.d.ts +76 -40
  22. package/dist/event-bus.d.ts +6 -1
  23. package/dist/index.d.ts +1 -9
  24. package/dist/reactive-query-manager.d.ts +14 -3
  25. package/dist/resource-manager.d.ts +35 -19
  26. package/dist/screen-manager.d.ts +4 -4
  27. package/dist/screen-types.d.ts +12 -11
  28. package/dist/src/bundles/audio.js +4 -0
  29. package/dist/src/bundles/audio.js.map +10 -0
  30. package/dist/src/bundles/bounds.js +4 -0
  31. package/dist/src/bundles/bounds.js.map +10 -0
  32. package/dist/src/bundles/camera.js +4 -0
  33. package/dist/src/bundles/camera.js.map +10 -0
  34. package/dist/src/bundles/collision.js +4 -0
  35. package/dist/src/bundles/collision.js.map +11 -0
  36. package/dist/src/bundles/diagnostics.js +5 -0
  37. package/dist/src/bundles/diagnostics.js.map +10 -0
  38. package/dist/src/bundles/input.js +4 -0
  39. package/dist/src/bundles/input.js.map +10 -0
  40. package/dist/src/bundles/physics2D.js +4 -0
  41. package/dist/src/bundles/physics2D.js.map +11 -0
  42. package/dist/src/bundles/renderers/renderer2D.js +4 -0
  43. package/dist/src/bundles/renderers/renderer2D.js.map +10 -0
  44. package/dist/src/bundles/spatial-index.js +4 -0
  45. package/dist/src/bundles/spatial-index.js.map +11 -0
  46. package/dist/src/bundles/state-machine.js +4 -0
  47. package/dist/src/bundles/state-machine.js.map +10 -0
  48. package/dist/src/bundles/timers.js +4 -0
  49. package/dist/src/bundles/timers.js.map +10 -0
  50. package/dist/src/bundles/transform.js +4 -0
  51. package/dist/src/bundles/transform.js.map +10 -0
  52. package/dist/src/bundles/tween.js +4 -0
  53. package/dist/src/bundles/tween.js.map +11 -0
  54. package/dist/src/index.js +4 -0
  55. package/dist/src/index.js.map +25 -0
  56. package/dist/system-builder.d.ts +36 -42
  57. package/dist/type-utils.d.ts +52 -3
  58. package/dist/types.d.ts +10 -19
  59. package/dist/utils/check-required-cycle.d.ts +12 -0
  60. package/dist/utils/easing.d.ts +71 -0
  61. package/dist/utils/math.d.ts +67 -0
  62. package/dist/utils/narrowphase.d.ts +63 -0
  63. package/dist/utils/spatial-hash.d.ts +53 -0
  64. package/package.json +50 -20
  65. package/dist/bundles/renderers/renderer2D.js +0 -4
  66. package/dist/bundles/renderers/renderer2D.js.map +0 -10
  67. package/dist/bundles/utils/bounds.js +0 -4
  68. package/dist/bundles/utils/bounds.js.map +0 -10
  69. package/dist/bundles/utils/collision.d.ts +0 -204
  70. package/dist/bundles/utils/collision.js +0 -4
  71. package/dist/bundles/utils/collision.js.map +0 -10
  72. package/dist/bundles/utils/input.js +0 -4
  73. package/dist/bundles/utils/input.js.map +0 -10
  74. package/dist/bundles/utils/movement.d.ts +0 -86
  75. package/dist/bundles/utils/movement.js +0 -4
  76. package/dist/bundles/utils/movement.js.map +0 -10
  77. package/dist/bundles/utils/timers.js +0 -4
  78. package/dist/bundles/utils/timers.js.map +0 -10
  79. package/dist/bundles/utils/transform.js +0 -4
  80. package/dist/bundles/utils/transform.js.map +0 -10
  81. package/dist/index.js +0 -4
  82. package/dist/index.js.map +0 -22
@@ -0,0 +1,197 @@
1
+ /**
2
+ * Tween Bundle for ECSpresso
3
+ *
4
+ * Declarative property animation within the ECS. Tween any numeric component
5
+ * field over time with standard easing functions, sequences, and completion events.
6
+ */
7
+ import { Bundle } from 'ecspresso';
8
+ import type { SystemPhase, ComponentsOfWorld, EventsOfWorld } from 'ecspresso';
9
+ import { type EasingFn } from '../utils/easing';
10
+ /**
11
+ * Data structure published when a tween completes.
12
+ * Use this type when defining tween completion events in your EventTypes interface.
13
+ */
14
+ export interface TweenEventData {
15
+ /** The entity ID the tween belongs to */
16
+ entityId: number;
17
+ /** Number of steps in the tween */
18
+ stepCount: number;
19
+ }
20
+ /**
21
+ * Extracts event names from EventTypes that have TweenEventData as their payload.
22
+ * This ensures only compatible events can be used with tween.onComplete.
23
+ * Uses `keyof EventTypes & string` to exclude number/symbol keys, ensuring the
24
+ * result is always a string subtype and Tween<E> is assignable to Tween<Record<string, any>>.
25
+ */
26
+ export type TweenEventName<EventTypes extends Record<string, any>> = {
27
+ [K in keyof EventTypes & string]: EventTypes[K] extends TweenEventData ? K : never;
28
+ }[keyof EventTypes & string];
29
+ export interface TweenTarget {
30
+ /** Component name on the entity */
31
+ component: string;
32
+ /** Pre-split field path (e.g., ['position', 'x']) */
33
+ path: readonly string[];
34
+ /** Starting value. null = resolve from current value on first tick */
35
+ from: number | null;
36
+ /** Target value */
37
+ to: number;
38
+ }
39
+ export interface TweenStep {
40
+ targets: TweenTarget[];
41
+ duration: number;
42
+ easing: EasingFn;
43
+ }
44
+ export interface Tween<EventTypes extends Record<string, any> = Record<string, any>> {
45
+ steps: TweenStep[];
46
+ currentStep: number;
47
+ elapsed: number;
48
+ loop: LoopMode;
49
+ totalLoops: number;
50
+ completedLoops: number;
51
+ direction: 1 | -1;
52
+ state: 'pending' | 'active' | 'complete';
53
+ onComplete?: TweenEventName<EventTypes>;
54
+ justFinished: boolean;
55
+ }
56
+ export type LoopMode = 'once' | 'loop' | 'yoyo';
57
+ /**
58
+ * Component types provided by the tween bundle.
59
+ */
60
+ export interface TweenComponentTypes<EventTypes extends Record<string, any> = Record<string, any>> {
61
+ tween: Tween<EventTypes>;
62
+ }
63
+ export interface TweenBundleOptions<G extends string = 'tweens'> {
64
+ /** System group name (default: 'tweens') */
65
+ systemGroup?: G;
66
+ /** Priority for tween update system (default: 0) */
67
+ priority?: number;
68
+ /** Execution phase (default: 'update') */
69
+ phase?: SystemPhase;
70
+ }
71
+ export interface TweenOptions<EventTypes extends Record<string, any> = Record<string, any>> {
72
+ /** Explicit starting value (default: captures current value on first tick) */
73
+ from?: number;
74
+ /** Easing function (default: linear) */
75
+ easing?: EasingFn;
76
+ /** Loop mode (default: 'once') */
77
+ loop?: LoopMode;
78
+ /** Number of loops. -1 = infinite (default: 1) */
79
+ loops?: number;
80
+ /** Event name to publish when tween completes */
81
+ onComplete?: TweenEventName<EventTypes>;
82
+ }
83
+ /**
84
+ * Create a single-target tween component.
85
+ *
86
+ * @param component Component name on the entity
87
+ * @param field Field path (dot-separated for nested, e.g. 'position.x')
88
+ * @param to Target value
89
+ * @param duration Duration in seconds
90
+ * @param options Optional configuration
91
+ * @returns Component object suitable for spreading into spawn()
92
+ */
93
+ export declare function createTween<EventTypes extends Record<string, any> = Record<string, any>>(component: string, field: string, to: number, duration: number, options?: TweenOptions<EventTypes>): Pick<TweenComponentTypes<EventTypes>, 'tween'>;
94
+ export interface TweenSequenceStepInput {
95
+ targets: ReadonlyArray<{
96
+ component: string;
97
+ field: string;
98
+ to: number;
99
+ from?: number;
100
+ }>;
101
+ duration: number;
102
+ easing?: EasingFn;
103
+ }
104
+ export interface TweenSequenceOptions<EventTypes extends Record<string, any> = Record<string, any>> {
105
+ /** Loop mode (default: 'once') */
106
+ loop?: LoopMode;
107
+ /** Number of loops. -1 = infinite (default: 1) */
108
+ loops?: number;
109
+ /** Event name to publish when tween completes */
110
+ onComplete?: TweenEventName<EventTypes>;
111
+ }
112
+ /**
113
+ * Create a multi-step tween sequence. Each step can have parallel targets.
114
+ *
115
+ * @param steps Array of step definitions
116
+ * @param options Optional configuration
117
+ * @returns Component object suitable for spreading into spawn()
118
+ */
119
+ export declare function createTweenSequence<EventTypes extends Record<string, any> = Record<string, any>>(steps: ReadonlyArray<TweenSequenceStepInput>, options?: TweenSequenceOptions<EventTypes>): Pick<TweenComponentTypes<EventTypes>, 'tween'>;
120
+ type AnyECSpresso = import('ecspresso').default<any, any, any, any, any, any, any>;
121
+ /**
122
+ * Recursively produce a union of dot-separated paths that resolve to `number`
123
+ * within type T. Depth-limited to 4 levels to prevent TS recursion errors.
124
+ *
125
+ * @example
126
+ * NumericPaths<{ x: number; y: number }> // 'x' | 'y'
127
+ * NumericPaths<{ position: { x: number }; rotation: number }> // 'position.x' | 'rotation'
128
+ */
129
+ export type NumericPaths<T, Depth extends readonly unknown[] = []> = Depth['length'] extends 4 ? never : T extends readonly unknown[] ? never : T extends Record<string, unknown> ? {
130
+ [K in keyof T & string]: NonNullable<T[K]> extends number ? K : NonNullable<T[K]> extends readonly unknown[] ? never : NonNullable<T[K]> extends Record<string, unknown> ? `${K}.${NumericPaths<NonNullable<T[K]>, [...Depth, unknown]>}` : never;
131
+ }[keyof T & string] : never;
132
+ /**
133
+ * Discriminated union over component names: each variant constrains `field`
134
+ * to the numeric paths of that component. TS narrows inline object literals
135
+ * by `component` discriminant — zero runtime overhead.
136
+ */
137
+ export type TypedTweenTargetInput<C extends Record<string, any>> = {
138
+ [K in keyof C & string]: {
139
+ component: K;
140
+ field: NumericPaths<C[K]>;
141
+ to: number;
142
+ from?: number;
143
+ };
144
+ }[keyof C & string];
145
+ export interface TypedTweenSequenceStepInput<C extends Record<string, any>> {
146
+ targets: ReadonlyArray<TypedTweenTargetInput<C>>;
147
+ duration: number;
148
+ easing?: EasingFn;
149
+ }
150
+ export interface TweenKit<W extends AnyECSpresso, G extends string = 'tweens'> {
151
+ bundle: Bundle<TweenComponentTypes<EventsOfWorld<W>>, EventsOfWorld<W>, {}, {}, {}, 'tween-update', G>;
152
+ createTween: <K extends keyof ComponentsOfWorld<W> & string>(component: K, field: NumericPaths<ComponentsOfWorld<W>[K]>, to: number, duration: number, options?: TweenOptions<EventsOfWorld<W>>) => Pick<TweenComponentTypes<EventsOfWorld<W>>, 'tween'>;
153
+ createTweenSequence: (steps: ReadonlyArray<TypedTweenSequenceStepInput<ComponentsOfWorld<W>>>, options?: TweenSequenceOptions<EventsOfWorld<W>>) => Pick<TweenComponentTypes<EventsOfWorld<W>>, 'tween'>;
154
+ }
155
+ /**
156
+ * Create a typed tween kit that captures the world type W.
157
+ *
158
+ * The returned `createTween` and `createTweenSequence` validate component names
159
+ * and field paths at compile time. Runtime behavior is identical to the standalone
160
+ * functions — all validation is type-level only.
161
+ *
162
+ * @template W - Concrete ECS world type (e.g. `typeof ecs`)
163
+ * @template G - System group name (default: 'tweens')
164
+ * @param options - Optional bundle configuration (same as createTweenBundle)
165
+ * @returns A kit object with bundle, createTween, createTweenSequence
166
+ *
167
+ * @example
168
+ * ```typescript
169
+ * const kit = createTweenKit<typeof ecs>();
170
+ * // or: const kit = createTweenKit<ECS>();
171
+ *
172
+ * const ecs = ECSpresso.create()
173
+ * .withBundle(kit.bundle)
174
+ * .build();
175
+ *
176
+ * // Type-safe: 'position' must be a component, 'x' must be a numeric field
177
+ * kit.createTween('position', 'x', 100, 1);
178
+ *
179
+ * // Type error: 'z' is not a field of position
180
+ * kit.createTween('position', 'z', 100, 1);
181
+ * ```
182
+ */
183
+ export declare function createTweenKit<W extends AnyECSpresso, G extends string = 'tweens'>(options?: TweenBundleOptions<G>): TweenKit<W, G>;
184
+ /**
185
+ * Create a tween bundle for ECSpresso.
186
+ *
187
+ * This bundle provides:
188
+ * - Tween system that processes all tween components each frame
189
+ * - Support for single-field, multi-target, and multi-step sequences
190
+ * - 31 standard easing functions
191
+ * - Loop modes: once, loop, yoyo
192
+ * - `justFinished` flag for one-frame completion detection
193
+ * - `onComplete` event publishing
194
+ * - Change detection via markChanged
195
+ */
196
+ export declare function createTweenBundle<EventTypes extends Record<string, any> = Record<string, any>, G extends string = 'tweens'>(options?: TweenBundleOptions<G>): Bundle<TweenComponentTypes<EventTypes>, EventTypes, {}, {}, {}, 'tween-update', G>;
197
+ export {};
@@ -1,5 +1,5 @@
1
1
  import type ECSpresso from './ecspresso';
2
- import type { RemoveEntityOptions } from './types';
2
+ import type { Entity, RemoveEntityOptions } from './types';
3
3
  /**
4
4
  * CommandBuffer queues structural changes to be executed later.
5
5
  * This prevents ordering issues when modifying entities during system execution.
@@ -16,27 +16,27 @@ import type { RemoveEntityOptions } from './types';
16
16
  * ecs.commands.playback(ecs);
17
17
  * ```
18
18
  */
19
- export default class CommandBuffer<ComponentTypes extends Record<string, any> = {}, EventTypes extends Record<string, any> = {}, ResourceTypes extends Record<string, any> = {}> {
19
+ export default class CommandBuffer<ComponentTypes extends Record<string, any> = {}, EventTypes extends Record<string, any> = {}, ResourceTypes extends Record<string, any> = {}, AssetTypes extends Record<string, unknown> = {}, ScreenStates extends Record<string, any> = {}> {
20
20
  private commands;
21
21
  /**
22
22
  * Queue an entity removal command
23
- * @param entityId The ID of the entity to remove
23
+ * @param entityOrId The entity or entity ID to remove
24
24
  * @param options Optional removal options (cascade, etc.)
25
25
  */
26
- removeEntity(entityId: number, options?: RemoveEntityOptions): void;
26
+ removeEntity(entityOrId: number | Entity<ComponentTypes>, options?: RemoveEntityOptions): void;
27
27
  /**
28
28
  * Queue a component addition command
29
- * @param entityId The ID of the entity
29
+ * @param entityOrId The entity or entity ID
30
30
  * @param componentName The name of the component to add
31
31
  * @param componentValue The component data
32
32
  */
33
- addComponent<K extends keyof ComponentTypes>(entityId: number, componentName: K, componentValue: ComponentTypes[K]): void;
33
+ addComponent<K extends keyof ComponentTypes>(entityOrId: number | Entity<ComponentTypes>, componentName: K, componentValue: ComponentTypes[K]): void;
34
34
  /**
35
35
  * Queue a component removal command
36
- * @param entityId The ID of the entity
36
+ * @param entityOrId The entity or entity ID
37
37
  * @param componentName The name of the component to remove
38
38
  */
39
- removeComponent<K extends keyof ComponentTypes>(entityId: number, componentName: K): void;
39
+ removeComponent<K extends keyof ComponentTypes>(entityOrId: number | Entity<ComponentTypes>, componentName: K): void;
40
40
  /**
41
41
  * Queue an entity spawn command
42
42
  * @param components The initial components for the new entity
@@ -47,43 +47,43 @@ export default class CommandBuffer<ComponentTypes extends Record<string, any> =
47
47
  }>(components: T & Record<Exclude<keyof T, keyof ComponentTypes>, never>): void;
48
48
  /**
49
49
  * Queue a child entity spawn command
50
- * @param parentId The ID of the parent entity
50
+ * @param parentOrId The parent entity or entity ID
51
51
  * @param components The initial components for the new child entity
52
52
  */
53
53
  spawnChild<T extends {
54
54
  [K in keyof ComponentTypes]?: ComponentTypes[K];
55
- }>(parentId: number, components: T & Record<Exclude<keyof T, keyof ComponentTypes>, never>): void;
55
+ }>(parentOrId: number | Entity<ComponentTypes>, components: T & Record<Exclude<keyof T, keyof ComponentTypes>, never>): void;
56
56
  /**
57
57
  * Queue multiple component additions
58
- * @param entityId The ID of the entity
58
+ * @param entityOrId The entity or entity ID
59
59
  * @param components Object with component names as keys and component data as values
60
60
  */
61
61
  addComponents<T extends {
62
62
  [K in keyof ComponentTypes]?: ComponentTypes[K];
63
- }>(entityId: number, components: T & Record<Exclude<keyof T, keyof ComponentTypes>, never>): void;
63
+ }>(entityOrId: number | Entity<ComponentTypes>, components: T & Record<Exclude<keyof T, keyof ComponentTypes>, never>): void;
64
64
  /**
65
65
  * Queue a parent assignment command
66
- * @param childId The ID of the child entity
67
- * @param parentId The ID of the parent entity
66
+ * @param childOrId The child entity or entity ID
67
+ * @param parentOrId The parent entity or entity ID
68
68
  */
69
- setParent(childId: number, parentId: number): void;
69
+ setParent(childOrId: number | Entity<ComponentTypes>, parentOrId: number | Entity<ComponentTypes>): void;
70
70
  /**
71
71
  * Queue a markChanged command
72
- * @param entityId The ID of the entity
72
+ * @param entityOrId The entity or entity ID
73
73
  * @param componentName The component to mark as changed
74
74
  */
75
- markChanged<K extends keyof ComponentTypes>(entityId: number, componentName: K): void;
75
+ markChanged<K extends keyof ComponentTypes>(entityOrId: number | Entity<ComponentTypes>, componentName: K): void;
76
76
  /**
77
77
  * Queue a parent removal command
78
- * @param childId The ID of the child entity
78
+ * @param childOrId The child entity or entity ID
79
79
  */
80
- removeParent(childId: number): void;
80
+ removeParent(childOrId: number | Entity<ComponentTypes>): void;
81
81
  /**
82
82
  * Execute all queued commands in FIFO order.
83
83
  * Errors from individual commands are caught and logged, but do not stop playback.
84
84
  * @param ecs The ECSpresso instance to execute commands on
85
85
  */
86
- playback<AssetTypes extends Record<string, any> = {}, ScreenStates extends Record<string, any> = {}>(ecs: ECSpresso<ComponentTypes, EventTypes, ResourceTypes, AssetTypes, ScreenStates>): void;
86
+ playback(ecs: ECSpresso<ComponentTypes, EventTypes, ResourceTypes, AssetTypes, ScreenStates>): void;
87
87
  /**
88
88
  * Clear all queued commands without executing them
89
89
  */
@@ -0,0 +1,165 @@
1
+ import type ECSpresso from "./ecspresso";
2
+ import type { ResourceFactoryWithDeps } from "./resource-manager";
3
+ import type Bundle from "./bundle";
4
+ import type { BundlesAreCompatible, TypesAreCompatible } from "./type-utils";
5
+ import type { AssetConfigurator, AssetsResource } from "./asset-types";
6
+ import type { ScreenDefinition, ScreenConfigurator, ScreenResource } from "./screen-types";
7
+ /**
8
+ * Helper type: finalize built-in resources ($assets, $screen) in the resource map.
9
+ * Auto-injects $assets/$screen when bundles contribute asset/screen types even without
10
+ * explicit withAssets()/withScreens(). Also narrows the AssetGroupNames on $assets.
11
+ */
12
+ type FinalizeBuiltinResources<R, A extends Record<string, unknown>, S extends Record<string, ScreenDefinition<any, any>>, AG extends string> = Omit<R, '$assets' | '$screen'> & ([keyof A] extends [never] ? {} : {
13
+ $assets: AssetsResource<A, AG>;
14
+ }) & ([keyof S] extends [never] ? {} : {
15
+ $screen: ScreenResource<S>;
16
+ });
17
+ /**
18
+ * Builder class for ECSpresso that provides fluent type-safe bundle installation.
19
+ * Handles type checking during build process to ensure type safety.
20
+ */
21
+ export declare class ECSpressoBuilder<C extends Record<string, any> = {}, E extends Record<string, any> = {}, R extends Record<string, any> = {}, A extends Record<string, unknown> = {}, S extends Record<string, ScreenDefinition<any, any>> = {}, Labels extends string = never, Groups extends string = never, AssetGroupNames extends string = never, ReactiveQueryNames extends string = never> {
22
+ /** The ECSpresso instance being built*/
23
+ private ecspresso;
24
+ /** Asset configurator for collecting asset definitions */
25
+ private assetConfigurator;
26
+ /** Screen configurator for collecting screen definitions */
27
+ private screenConfigurator;
28
+ /** Pending resources to add during build */
29
+ private pendingResources;
30
+ /** Pending dispose callbacks to register during build */
31
+ private pendingDisposeCallbacks;
32
+ /** Pending required component registrations to apply during build */
33
+ private pendingRequiredComponents;
34
+ /** Fixed timestep interval (null means use default 1/60) */
35
+ private _fixedDt;
36
+ constructor();
37
+ /**
38
+ * Add the first bundle when starting with empty types.
39
+ * This overload allows any bundle to be added to an empty ECSpresso instance.
40
+ */
41
+ withBundle<BC extends Record<string, any>, BE extends Record<string, any>, BR extends Record<string, any>, BA extends Record<string, unknown> = {}, BS extends Record<string, ScreenDefinition<any, any>> = {}, BL extends string = never, BG extends string = never, BAG extends string = never, BRQ extends string = never>(this: ECSpressoBuilder<{}, {}, {}, A, S, Labels, Groups, AssetGroupNames, ReactiveQueryNames>, bundle: Bundle<BC, BE, BR, BA, BS, BL, BG, BAG, BRQ>): ECSpressoBuilder<BC, BE, BR, A & BA, S & BS, Labels | BL, Groups | BG, AssetGroupNames | BAG, ReactiveQueryNames | BRQ>;
42
+ /**
43
+ * Add a subsequent bundle with type checking.
44
+ * This overload enforces bundle type compatibility.
45
+ */
46
+ withBundle<BC extends Record<string, any>, BE extends Record<string, any>, BR extends Record<string, any>, BA extends Record<string, unknown> = {}, BS extends Record<string, ScreenDefinition<any, any>> = {}, BL extends string = never, BG extends string = never, BAG extends string = never, BRQ extends string = never>(bundle: BundlesAreCompatible<C, BC, E, BE, R, BR, A, BA, S, BS> extends true ? Bundle<BC, BE, BR, BA, BS, BL, BG, BAG, BRQ> : never): ECSpressoBuilder<C & BC, E & BE, R & BR, A & BA, S & BS, Labels | BL, Groups | BG, AssetGroupNames | BAG, ReactiveQueryNames | BRQ>;
47
+ /**
48
+ * Add application-specific component types to the builder chain.
49
+ * This is a pure type-level operation with no runtime cost.
50
+ * Conflicts with existing component types (same key, different type) produce a `never` return.
51
+ */
52
+ withComponentTypes<T extends Record<string, any>>(): TypesAreCompatible<C, T> extends true ? ECSpressoBuilder<C & T, E, R, A, S, Labels, Groups, AssetGroupNames, ReactiveQueryNames> : never;
53
+ /**
54
+ * Add application-specific event types to the builder chain.
55
+ * This is a pure type-level operation with no runtime cost.
56
+ * Conflicts with existing event types (same key, different type) produce a `never` return.
57
+ */
58
+ withEventTypes<T extends Record<string, any>>(): TypesAreCompatible<E, T> extends true ? ECSpressoBuilder<C, E & T, R, A, S, Labels, Groups, AssetGroupNames, ReactiveQueryNames> : never;
59
+ /**
60
+ * Add a resource during ECSpresso construction
61
+ * @param key The resource key
62
+ * @param resource The resource value, factory function, or factory with dependencies/disposal
63
+ * @returns This builder with updated resource types
64
+ *
65
+ * @example
66
+ * ```typescript
67
+ * ECSpresso.create<Components, Events, Resources>()
68
+ * .withResource('config', { debug: true })
69
+ * .withResource('counter', () => 42)
70
+ * .withResource('derived', {
71
+ * dependsOn: ['base'],
72
+ * factory: (ecs) => ecs.getResource('base') * 2,
73
+ * onDispose: (value) => console.log('Disposed:', value)
74
+ * })
75
+ * .build();
76
+ * ```
77
+ */
78
+ withResource<K extends string, V>(key: K, resource: V | ((context: ECSpresso<C, E, R & Record<K, V>, A, S>) => V | Promise<V>) | ResourceFactoryWithDeps<V, ECSpresso<C, E, R & Record<K, V>, A, S>, keyof (R & Record<K, V>) & string>): ECSpressoBuilder<C, E, R & Record<K, V>, A, S, Labels, Groups, AssetGroupNames, ReactiveQueryNames>;
79
+ /**
80
+ * Register a dispose callback for a component type during build.
81
+ * Called when a component is removed (explicit removal, entity destruction, or replacement).
82
+ * @param componentName The component type to register disposal for
83
+ * @param callback Function receiving the component value being disposed
84
+ * @returns This builder for method chaining
85
+ */
86
+ withDispose<K extends keyof C & string>(componentName: K, callback: (value: C[K]) => void): this;
87
+ /**
88
+ * Register a required component relationship during build.
89
+ * When an entity gains `trigger`, the `required` component is auto-added
90
+ * (using `factory` for the default value) if not already present.
91
+ * @param trigger The component whose presence triggers auto-addition
92
+ * @param required The component to auto-add
93
+ * @param factory Function that creates the default value for the required component
94
+ * @returns This builder for method chaining
95
+ */
96
+ withRequired<Trigger extends keyof C & string, Required extends keyof C & string>(trigger: Trigger, required: Required, factory: (triggerValue: C[Trigger]) => C[Required]): this;
97
+ /**
98
+ * Configure assets for this ECSpresso instance
99
+ * @param configurator Function that receives an AssetConfigurator and returns it after adding assets
100
+ * @returns This builder with updated asset types
101
+ *
102
+ * @example
103
+ * ```typescript
104
+ * ECSpresso.create<Components, Events, Resources>()
105
+ * .withAssets(assets => assets
106
+ * .add('playerSprite', () => loadTexture('player.png'))
107
+ * .addGroup('level1', {
108
+ * background: () => loadTexture('level1-bg.png'),
109
+ * music: () => loadAudio('level1.mp3'),
110
+ * })
111
+ * )
112
+ * .build();
113
+ * ```
114
+ */
115
+ withAssets<NewA extends Record<string, unknown>, NewG extends string = never>(configurator: (assets: AssetConfigurator<{}, never>) => AssetConfigurator<NewA, NewG>): ECSpressoBuilder<C, E, R & {
116
+ $assets: AssetsResource<A & NewA, string>;
117
+ }, A & NewA, S, Labels, Groups, AssetGroupNames | NewG, ReactiveQueryNames>;
118
+ /**
119
+ * Configure screens for this ECSpresso instance
120
+ * @param configurator Function that receives a ScreenConfigurator and returns it after adding screens
121
+ * @returns This builder with updated screen types
122
+ *
123
+ * @example
124
+ * ```typescript
125
+ * ECSpresso.create<Components, Events, Resources>()
126
+ * .withScreens(screens => screens
127
+ * .add('loading', {
128
+ * initialState: () => ({ progress: 0 }),
129
+ * })
130
+ * .add('gameplay', {
131
+ * initialState: ({ level }) => ({ score: 0, level }),
132
+ * requiredAssetGroups: ['level1'],
133
+ * })
134
+ * )
135
+ * .build();
136
+ * ```
137
+ */
138
+ withScreens<NewS extends Record<string, ScreenDefinition<any, any>>>(configurator: (screens: ScreenConfigurator<{}, ECSpresso<C, E, R, A, Record<string, ScreenDefinition>>>) => ScreenConfigurator<NewS, ECSpresso<C, E, R, A, Record<string, ScreenDefinition>>>): ECSpressoBuilder<C, E, R & {
139
+ $screen: ScreenResource<S & NewS>;
140
+ }, A, S & NewS, Labels, Groups, AssetGroupNames, ReactiveQueryNames>;
141
+ /**
142
+ * Configure the fixed timestep interval for the fixedUpdate phase.
143
+ * @param dt The fixed timestep in seconds (e.g., 1/60 for 60Hz physics)
144
+ * @returns This builder for method chaining
145
+ */
146
+ withFixedTimestep(dt: number): this;
147
+ /**
148
+ * Declare reactive query names that will be registered at runtime.
149
+ * This is a pure type-level operation with no runtime cost.
150
+ */
151
+ withReactiveQueryNames<N extends string>(): ECSpressoBuilder<C, E, R, A, S, Labels, Groups, AssetGroupNames, ReactiveQueryNames | N>;
152
+ /**
153
+ * Complete the build process and return the built ECSpresso instance
154
+ */
155
+ build(): ECSpresso<C, E, FinalizeBuiltinResources<R, A, S, [AssetGroupNames] extends [never] ? string : AssetGroupNames>, A, S, [
156
+ Labels
157
+ ] extends [never] ? string : Labels, [
158
+ Groups
159
+ ] extends [never] ? string : Groups, [
160
+ AssetGroupNames
161
+ ] extends [never] ? string : AssetGroupNames, [
162
+ ReactiveQueryNames
163
+ ] extends [never] ? string : ReactiveQueryNames>;
164
+ }
165
+ export {};