ecspresso 0.11.0 → 0.12.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 (96) hide show
  1. package/README.md +200 -148
  2. package/dist/asset-manager.d.ts +1 -1
  3. package/dist/asset-types.d.ts +2 -2
  4. package/dist/command-buffer.d.ts +34 -24
  5. package/dist/ecspresso-builder.d.ts +100 -72
  6. package/dist/ecspresso.d.ts +257 -122
  7. package/dist/entity-manager.d.ts +57 -47
  8. package/dist/index.d.ts +5 -4
  9. package/dist/plugin.d.ts +61 -0
  10. package/dist/{bundles → plugins}/audio.d.ts +27 -47
  11. package/dist/{bundles → plugins}/bounds.d.ts +17 -25
  12. package/dist/{bundles → plugins}/camera.d.ts +8 -9
  13. package/dist/{bundles → plugins}/collision.d.ts +22 -26
  14. package/dist/plugins/coroutine.d.ts +126 -0
  15. package/dist/{bundles → plugins}/diagnostics.d.ts +5 -4
  16. package/dist/{bundles → plugins}/input.d.ts +9 -15
  17. package/dist/plugins/particles.d.ts +225 -0
  18. package/dist/{bundles → plugins}/physics2D.d.ts +27 -23
  19. package/dist/{bundles → plugins}/renderers/renderer2D.d.ts +40 -39
  20. package/dist/{bundles → plugins}/spatial-index.d.ts +11 -10
  21. package/dist/plugins/sprite-animation.d.ts +150 -0
  22. package/dist/{bundles → plugins}/state-machine.d.ts +50 -104
  23. package/dist/plugins/timers.d.ts +151 -0
  24. package/dist/{bundles → plugins}/transform.d.ts +18 -19
  25. package/dist/{bundles → plugins}/tween.d.ts +36 -71
  26. package/dist/resource-manager.d.ts +32 -7
  27. package/dist/screen-manager.d.ts +17 -11
  28. package/dist/screen-types.d.ts +5 -2
  29. package/dist/src/index.js +2 -2
  30. package/dist/src/index.js.map +17 -17
  31. package/dist/src/plugins/audio.js +4 -0
  32. package/dist/src/plugins/audio.js.map +10 -0
  33. package/dist/src/plugins/bounds.js +4 -0
  34. package/dist/src/plugins/bounds.js.map +10 -0
  35. package/dist/src/plugins/camera.js +4 -0
  36. package/dist/src/plugins/camera.js.map +10 -0
  37. package/dist/src/plugins/collision.js +4 -0
  38. package/dist/src/plugins/collision.js.map +11 -0
  39. package/dist/src/plugins/coroutine.js +4 -0
  40. package/dist/src/plugins/coroutine.js.map +10 -0
  41. package/dist/src/plugins/diagnostics.js +5 -0
  42. package/dist/src/plugins/diagnostics.js.map +10 -0
  43. package/dist/src/plugins/input.js +4 -0
  44. package/dist/src/plugins/input.js.map +10 -0
  45. package/dist/src/plugins/particles.js +4 -0
  46. package/dist/src/plugins/particles.js.map +10 -0
  47. package/dist/src/plugins/physics2D.js +4 -0
  48. package/dist/src/plugins/physics2D.js.map +11 -0
  49. package/dist/src/plugins/renderers/renderer2D.js +4 -0
  50. package/dist/src/plugins/renderers/renderer2D.js.map +10 -0
  51. package/dist/src/plugins/spatial-index.js +4 -0
  52. package/dist/src/plugins/spatial-index.js.map +11 -0
  53. package/dist/src/plugins/sprite-animation.js +4 -0
  54. package/dist/src/plugins/sprite-animation.js.map +10 -0
  55. package/dist/src/plugins/state-machine.js +4 -0
  56. package/dist/src/plugins/state-machine.js.map +10 -0
  57. package/dist/src/plugins/timers.js +4 -0
  58. package/dist/src/plugins/timers.js.map +10 -0
  59. package/dist/src/plugins/transform.js +4 -0
  60. package/dist/src/plugins/transform.js.map +10 -0
  61. package/dist/src/plugins/tween.js +4 -0
  62. package/dist/src/plugins/tween.js.map +11 -0
  63. package/dist/system-builder.d.ts +66 -97
  64. package/dist/type-utils.d.ts +218 -27
  65. package/dist/types.d.ts +52 -24
  66. package/dist/utils/check-required-cycle.d.ts +1 -1
  67. package/dist/utils/narrowphase.d.ts +7 -7
  68. package/package.json +53 -45
  69. package/dist/bundle.d.ts +0 -173
  70. package/dist/bundles/timers.d.ts +0 -173
  71. package/dist/src/bundles/audio.js +0 -4
  72. package/dist/src/bundles/audio.js.map +0 -10
  73. package/dist/src/bundles/bounds.js +0 -4
  74. package/dist/src/bundles/bounds.js.map +0 -10
  75. package/dist/src/bundles/camera.js +0 -4
  76. package/dist/src/bundles/camera.js.map +0 -10
  77. package/dist/src/bundles/collision.js +0 -4
  78. package/dist/src/bundles/collision.js.map +0 -11
  79. package/dist/src/bundles/diagnostics.js +0 -5
  80. package/dist/src/bundles/diagnostics.js.map +0 -10
  81. package/dist/src/bundles/input.js +0 -4
  82. package/dist/src/bundles/input.js.map +0 -10
  83. package/dist/src/bundles/physics2D.js +0 -4
  84. package/dist/src/bundles/physics2D.js.map +0 -11
  85. package/dist/src/bundles/renderers/renderer2D.js +0 -4
  86. package/dist/src/bundles/renderers/renderer2D.js.map +0 -10
  87. package/dist/src/bundles/spatial-index.js +0 -4
  88. package/dist/src/bundles/spatial-index.js.map +0 -11
  89. package/dist/src/bundles/state-machine.js +0 -4
  90. package/dist/src/bundles/state-machine.js.map +0 -10
  91. package/dist/src/bundles/timers.js +0 -4
  92. package/dist/src/bundles/timers.js.map +0 -10
  93. package/dist/src/bundles/transform.js +0 -4
  94. package/dist/src/bundles/transform.js.map +0 -10
  95. package/dist/src/bundles/tween.js +0 -4
  96. package/dist/src/bundles/tween.js.map +0 -11
@@ -1,5 +1,6 @@
1
1
  import type ECSpresso from './ecspresso';
2
- import type { Entity, RemoveEntityOptions } from './types';
2
+ import type { RemoveEntityOptions } from './types';
3
+ import type { WorldConfig, EmptyConfig } from './type-utils';
3
4
  /**
4
5
  * CommandBuffer queues structural changes to be executed later.
5
6
  * This prevents ordering issues when modifying entities during system execution.
@@ -16,74 +17,83 @@ import type { Entity, RemoveEntityOptions } from './types';
16
17
  * ecs.commands.playback(ecs);
17
18
  * ```
18
19
  */
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
+ export default class CommandBuffer<Cfg extends WorldConfig = EmptyConfig> {
20
21
  private commands;
21
22
  /**
22
23
  * Queue an entity removal command
23
- * @param entityOrId The entity or entity ID to remove
24
+ * @param entityId The entity ID to remove
24
25
  * @param options Optional removal options (cascade, etc.)
25
26
  */
26
- removeEntity(entityOrId: number | Entity<ComponentTypes>, options?: RemoveEntityOptions): void;
27
+ removeEntity(entityId: number, options?: RemoveEntityOptions): void;
27
28
  /**
28
29
  * Queue a component addition command
29
- * @param entityOrId The entity or entity ID
30
+ * @param entityId The entity ID
30
31
  * @param componentName The name of the component to add
31
32
  * @param componentValue The component data
32
33
  */
33
- addComponent<K extends keyof ComponentTypes>(entityOrId: number | Entity<ComponentTypes>, componentName: K, componentValue: ComponentTypes[K]): void;
34
+ addComponent<K extends keyof Cfg['components']>(entityId: number, componentName: K, componentValue: Cfg['components'][K]): void;
34
35
  /**
35
36
  * Queue a component removal command
36
- * @param entityOrId The entity or entity ID
37
+ * @param entityId The entity ID
37
38
  * @param componentName The name of the component to remove
38
39
  */
39
- removeComponent<K extends keyof ComponentTypes>(entityOrId: number | Entity<ComponentTypes>, componentName: K): void;
40
+ removeComponent<K extends keyof Cfg['components']>(entityId: number, componentName: K): void;
40
41
  /**
41
42
  * Queue an entity spawn command
42
43
  * @param components The initial components for the new entity
43
44
  * @returns void (entity ID not available until playback)
44
45
  */
45
46
  spawn<T extends {
46
- [K in keyof ComponentTypes]?: ComponentTypes[K];
47
- }>(components: T & Record<Exclude<keyof T, keyof ComponentTypes>, never>): void;
47
+ [K in keyof Cfg['components']]?: Cfg['components'][K];
48
+ }>(components: T & Record<Exclude<keyof T, keyof Cfg['components']>, never>): void;
48
49
  /**
49
50
  * Queue a child entity spawn command
50
- * @param parentOrId The parent entity or entity ID
51
+ * @param parentId The parent entity ID
51
52
  * @param components The initial components for the new child entity
52
53
  */
53
54
  spawnChild<T extends {
54
- [K in keyof ComponentTypes]?: ComponentTypes[K];
55
- }>(parentOrId: number | Entity<ComponentTypes>, components: T & Record<Exclude<keyof T, keyof ComponentTypes>, never>): void;
55
+ [K in keyof Cfg['components']]?: Cfg['components'][K];
56
+ }>(parentId: number, components: T & Record<Exclude<keyof T, keyof Cfg['components']>, never>): void;
56
57
  /**
57
58
  * Queue multiple component additions
58
- * @param entityOrId The entity or entity ID
59
+ * @param entityId The entity ID
59
60
  * @param components Object with component names as keys and component data as values
60
61
  */
61
62
  addComponents<T extends {
62
- [K in keyof ComponentTypes]?: ComponentTypes[K];
63
- }>(entityOrId: number | Entity<ComponentTypes>, components: T & Record<Exclude<keyof T, keyof ComponentTypes>, never>): void;
63
+ [K in keyof Cfg['components']]?: Cfg['components'][K];
64
+ }>(entityId: number, components: T & Record<Exclude<keyof T, keyof Cfg['components']>, never>): void;
64
65
  /**
65
66
  * Queue a parent assignment command
66
- * @param childOrId The child entity or entity ID
67
- * @param parentOrId The parent entity or entity ID
67
+ * @param childId The child entity ID
68
+ * @param parentId The parent entity ID
68
69
  */
69
- setParent(childOrId: number | Entity<ComponentTypes>, parentOrId: number | Entity<ComponentTypes>): void;
70
+ setParent(childId: number, parentId: number): void;
71
+ /**
72
+ * Queue a component mutation command.
73
+ * The mutator runs during playback, receiving the component for in-place mutation.
74
+ * Automatically marks the component as changed.
75
+ * @param entityId The entity ID
76
+ * @param componentName The component to mutate
77
+ * @param mutator A function that receives the component value for in-place mutation
78
+ */
79
+ mutateComponent<K extends keyof Cfg['components']>(entityId: number, componentName: K, mutator: (value: Cfg['components'][K]) => void): void;
70
80
  /**
71
81
  * Queue a markChanged command
72
- * @param entityOrId The entity or entity ID
82
+ * @param entityId The entity ID
73
83
  * @param componentName The component to mark as changed
74
84
  */
75
- markChanged<K extends keyof ComponentTypes>(entityOrId: number | Entity<ComponentTypes>, componentName: K): void;
85
+ markChanged<K extends keyof Cfg['components']>(entityId: number, componentName: K): void;
76
86
  /**
77
87
  * Queue a parent removal command
78
- * @param childOrId The child entity or entity ID
88
+ * @param childId The child entity ID
79
89
  */
80
- removeParent(childOrId: number | Entity<ComponentTypes>): void;
90
+ removeParent(childId: number): void;
81
91
  /**
82
92
  * Execute all queued commands in FIFO order.
83
93
  * Errors from individual commands are caught and logged, but do not stop playback.
84
94
  * @param ecs The ECSpresso instance to execute commands on
85
95
  */
86
- playback(ecs: ECSpresso<ComponentTypes, EventTypes, ResourceTypes, AssetTypes, ScreenStates>): void;
96
+ playback(ecs: ECSpresso<Cfg>): void;
87
97
  /**
88
98
  * Clear all queued commands without executing them
89
99
  */
@@ -1,24 +1,30 @@
1
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";
2
+ import type { ResourceFactoryWithDeps, ResourceDirectValue } from "./resource-manager";
3
+ import { type Plugin } from "./plugin";
4
+ import type { WorldConfig, EmptyConfig, ConfigsAreCompatible, MergeConfigs, TypesAreCompatible, RequirementsSatisfied, WithComponents, WithEvents, WithResources } from "./type-utils";
5
5
  import type { AssetConfigurator, AssetsResource } from "./asset-types";
6
6
  import type { ScreenDefinition, ScreenConfigurator, ScreenResource } from "./screen-types";
7
7
  /**
8
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
9
+ * Auto-injects $assets/$screen when plugins contribute asset/screen types even without
10
10
  * explicit withAssets()/withScreens(). Also narrows the AssetGroupNames on $assets.
11
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
- });
12
+ type FinalizeBuiltinResources<Cfg extends WorldConfig, AG extends string> = {
13
+ readonly components: Cfg['components'];
14
+ readonly events: Cfg['events'];
15
+ readonly resources: Omit<Cfg['resources'], '$assets' | '$screen'> & ([keyof Cfg['assets']] extends [never] ? {} : {
16
+ $assets: AssetsResource<Cfg['assets'], AG>;
17
+ }) & ([keyof Cfg['screens']] extends [never] ? {} : {
18
+ $screen: ScreenResource<Cfg['screens']>;
19
+ });
20
+ readonly assets: Cfg['assets'];
21
+ readonly screens: Cfg['screens'];
22
+ };
17
23
  /**
18
- * Builder class for ECSpresso that provides fluent type-safe bundle installation.
24
+ * Builder class for ECSpresso that provides fluent type-safe plugin installation.
19
25
  * Handles type checking during build process to ensure type safety.
20
26
  */
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> {
27
+ export declare class ECSpressoBuilder<Cfg extends WorldConfig = EmptyConfig, Labels extends string = never, Groups extends string = never, AssetGroupNames extends string = never, ReactiveQueryNames extends string = never> {
22
28
  /** The ECSpresso instance being built*/
23
29
  private ecspresso;
24
30
  /** Asset configurator for collecting asset definitions */
@@ -31,51 +37,66 @@ export declare class ECSpressoBuilder<C extends Record<string, any> = {}, E exte
31
37
  private pendingDisposeCallbacks;
32
38
  /** Pending required component registrations to apply during build */
33
39
  private pendingRequiredComponents;
40
+ /** Pending plugins to install during build */
41
+ private pendingPlugins;
34
42
  /** Fixed timestep interval (null means use default 1/60) */
35
43
  private _fixedDt;
36
44
  constructor();
37
45
  /**
38
- * Add the first bundle when starting with empty types.
39
- * This overload allows any bundle to be added to an empty ECSpresso instance.
46
+ * Add the first plugin when starting with empty types.
47
+ * This overload allows any plugin to be added to an empty ECSpresso instance.
48
+ * Only merges the plugin's Provides (PCfg) into accumulated config, not its Requires (PReq).
40
49
  */
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>;
50
+ withPlugin<PCfg extends WorldConfig, PReq extends WorldConfig = EmptyConfig, BL extends string = never, BG extends string = never, BAG extends string = never, BRQ extends string = never>(this: ECSpressoBuilder<{
51
+ readonly components: {};
52
+ readonly events: {};
53
+ readonly resources: {};
54
+ readonly assets: Cfg['assets'];
55
+ readonly screens: Cfg['screens'];
56
+ }, Labels, Groups, AssetGroupNames, ReactiveQueryNames>, plugin: Plugin<PCfg, PReq, BL, BG, BAG, BRQ>): ECSpressoBuilder<{
57
+ readonly components: PCfg['components'];
58
+ readonly events: PCfg['events'];
59
+ readonly resources: PCfg['resources'];
60
+ readonly assets: Cfg['assets'] & PCfg['assets'];
61
+ readonly screens: Cfg['screens'] & PCfg['screens'];
62
+ }, Labels | BL, Groups | BG, AssetGroupNames | BAG, ReactiveQueryNames | BRQ>;
42
63
  /**
43
- * Add a subsequent bundle with type checking.
44
- * This overload enforces bundle type compatibility.
64
+ * Add a subsequent plugin with type checking.
65
+ * This overload enforces plugin type compatibility and requirement satisfaction.
66
+ * Only merges the plugin's Provides (PCfg) into accumulated config, not its Requires (PReq).
45
67
  */
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>;
68
+ withPlugin<PCfg extends WorldConfig, PReq extends WorldConfig = EmptyConfig, BL extends string = never, BG extends string = never, BAG extends string = never, BRQ extends string = never>(plugin: ConfigsAreCompatible<Cfg, PCfg> extends true ? RequirementsSatisfied<Cfg, PReq> extends true ? Plugin<PCfg, PReq, BL, BG, BAG, BRQ> : never : never): ECSpressoBuilder<MergeConfigs<Cfg, PCfg>, Labels | BL, Groups | BG, AssetGroupNames | BAG, ReactiveQueryNames | BRQ>;
47
69
  /**
48
70
  * Add application-specific component types to the builder chain.
49
71
  * This is a pure type-level operation with no runtime cost.
50
72
  * Conflicts with existing component types (same key, different type) produce a `never` return.
51
73
  */
52
- withComponentTypes<T extends Record<string, any>>(): TypesAreCompatible<C, T> extends true ? ECSpressoBuilder<C & T, E, R, A, S, Labels, Groups, AssetGroupNames, ReactiveQueryNames> : never;
74
+ withComponentTypes<T extends Record<string, any>>(): TypesAreCompatible<Cfg['components'], T> extends true ? ECSpressoBuilder<WithComponents<Cfg, T>, Labels, Groups, AssetGroupNames, ReactiveQueryNames> : never;
53
75
  /**
54
76
  * Add application-specific event types to the builder chain.
55
77
  * This is a pure type-level operation with no runtime cost.
56
78
  * Conflicts with existing event types (same key, different type) produce a `never` return.
57
79
  */
58
- withEventTypes<T extends Record<string, any>>(): TypesAreCompatible<E, T> extends true ? ECSpressoBuilder<C, E & T, R, A, S, Labels, Groups, AssetGroupNames, ReactiveQueryNames> : never;
80
+ withEventTypes<T extends Record<string, any>>(): TypesAreCompatible<Cfg['events'], T> extends true ? ECSpressoBuilder<WithEvents<Cfg, T>, Labels, Groups, AssetGroupNames, ReactiveQueryNames> : never;
59
81
  /**
60
- * Add a resource during ECSpresso construction
82
+ * Add application-specific resource types to the builder chain.
83
+ * This is a pure type-level operation with no runtime cost.
84
+ * Conflicts with existing resource types (same key, different type) produce a `never` return.
85
+ */
86
+ withResourceTypes<T extends Record<string, any>>(): TypesAreCompatible<Cfg['resources'], T> extends true ? ECSpressoBuilder<WithResources<Cfg, T>, Labels, Groups, AssetGroupNames, ReactiveQueryNames> : never;
87
+ /**
88
+ * Add a resource during ECSpresso construction.
89
+ *
90
+ * When the key matches a pre-declared resource type (via `withResourceTypes`, `create<C,E,R>()`,
91
+ * or plugin resources), the value is validated against that type.
92
+ * For new keys, the value type is inferred as before.
93
+ *
61
94
  * @param key The resource key
62
95
  * @param resource The resource value, factory function, or factory with dependencies/disposal
63
96
  * @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
97
  */
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>;
98
+ withResource<K extends keyof Cfg['resources'] & string>(key: K, resource: Cfg['resources'][K] | ((context: ECSpresso<Cfg>) => Cfg['resources'][K] | Promise<Cfg['resources'][K]>) | ResourceFactoryWithDeps<Cfg['resources'][K], ECSpresso<Cfg>, keyof Cfg['resources'] & string> | ResourceDirectValue<Cfg['resources'][K]>): ECSpressoBuilder<Cfg, Labels, Groups, AssetGroupNames, ReactiveQueryNames>;
99
+ withResource<K extends string, V>(key: K & ([K] extends [keyof Cfg['resources']] ? [V] extends [Cfg['resources'][K & keyof Cfg['resources']]] ? string : never : string), resource: V | ((context: ECSpresso<WithResources<Cfg, Record<K, V>>>) => V | Promise<V>) | ResourceFactoryWithDeps<V, ECSpresso<WithResources<Cfg, Record<K, V>>>, keyof (Cfg['resources'] & Record<K, V>) & string> | ResourceDirectValue<V>): ECSpressoBuilder<WithResources<Cfg, Record<K, V>>, Labels, Groups, AssetGroupNames, ReactiveQueryNames>;
79
100
  /**
80
101
  * Register a dispose callback for a component type during build.
81
102
  * Called when a component is removed (explicit removal, entity destruction, or replacement).
@@ -83,7 +104,10 @@ export declare class ECSpressoBuilder<C extends Record<string, any> = {}, E exte
83
104
  * @param callback Function receiving the component value being disposed
84
105
  * @returns This builder for method chaining
85
106
  */
86
- withDispose<K extends keyof C & string>(componentName: K, callback: (value: C[K]) => void): this;
107
+ withDispose<K extends keyof Cfg['components'] & string>(componentName: K, callback: (ctx: {
108
+ value: Cfg['components'][K];
109
+ entityId: number;
110
+ }) => void): this;
87
111
  /**
88
112
  * Register a required component relationship during build.
89
113
  * When an entity gains `trigger`, the `required` component is auto-added
@@ -93,51 +117,47 @@ export declare class ECSpressoBuilder<C extends Record<string, any> = {}, E exte
93
117
  * @param factory Function that creates the default value for the required component
94
118
  * @returns This builder for method chaining
95
119
  */
96
- withRequired<Trigger extends keyof C & string, Required extends keyof C & string>(trigger: Trigger, required: Required, factory: (triggerValue: C[Trigger]) => C[Required]): this;
120
+ withRequired<Trigger extends keyof Cfg['components'] & string, Required extends keyof Cfg['components'] & string>(trigger: Trigger, required: Required, factory: (triggerValue: Cfg['components'][Trigger]) => Cfg['components'][Required]): this;
97
121
  /**
98
122
  * Configure assets for this ECSpresso instance
99
123
  * @param configurator Function that receives an AssetConfigurator and returns it after adding assets
100
124
  * @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
125
  */
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>;
126
+ withAssets<NewA extends Record<string, unknown>, NewG extends string = never>(configurator: (assets: AssetConfigurator<{}, never>) => AssetConfigurator<NewA, NewG>): ECSpressoBuilder<{
127
+ readonly components: Cfg['components'];
128
+ readonly events: Cfg['events'];
129
+ readonly resources: Cfg['resources'] & {
130
+ $assets: AssetsResource<Cfg['assets'] & NewA, string>;
131
+ };
132
+ readonly assets: Cfg['assets'] & NewA;
133
+ readonly screens: Cfg['screens'];
134
+ }, Labels, Groups, AssetGroupNames | NewG, ReactiveQueryNames>;
118
135
  /**
119
136
  * Configure screens for this ECSpresso instance
120
137
  * @param configurator Function that receives a ScreenConfigurator and returns it after adding screens
121
138
  * @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
139
  */
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>;
140
+ withScreens<NewS extends Record<string, ScreenDefinition<any, any>>>(configurator: (screens: ScreenConfigurator<{}, ECSpresso<{
141
+ readonly components: Cfg['components'];
142
+ readonly events: Cfg['events'];
143
+ readonly resources: Cfg['resources'];
144
+ readonly assets: Cfg['assets'];
145
+ readonly screens: Record<string, ScreenDefinition>;
146
+ }>>) => ScreenConfigurator<NewS, ECSpresso<{
147
+ readonly components: Cfg['components'];
148
+ readonly events: Cfg['events'];
149
+ readonly resources: Cfg['resources'];
150
+ readonly assets: Cfg['assets'];
151
+ readonly screens: Record<string, ScreenDefinition>;
152
+ }>>): ECSpressoBuilder<{
153
+ readonly components: Cfg['components'];
154
+ readonly events: Cfg['events'];
155
+ readonly resources: Cfg['resources'] & {
156
+ $screen: ScreenResource<Cfg['screens'] & NewS>;
157
+ };
158
+ readonly assets: Cfg['assets'];
159
+ readonly screens: Cfg['screens'] & NewS;
160
+ }, Labels, Groups, AssetGroupNames, ReactiveQueryNames>;
141
161
  /**
142
162
  * Configure the fixed timestep interval for the fixedUpdate phase.
143
163
  * @param dt The fixed timestep in seconds (e.g., 1/60 for 60Hz physics)
@@ -148,11 +168,19 @@ export declare class ECSpressoBuilder<C extends Record<string, any> = {}, E exte
148
168
  * Declare reactive query names that will be registered at runtime.
149
169
  * This is a pure type-level operation with no runtime cost.
150
170
  */
151
- withReactiveQueryNames<N extends string>(): ECSpressoBuilder<C, E, R, A, S, Labels, Groups, AssetGroupNames, ReactiveQueryNames | N>;
171
+ withReactiveQueryNames<N extends string>(): ECSpressoBuilder<Cfg, Labels, Groups, AssetGroupNames, ReactiveQueryNames | N>;
172
+ /**
173
+ * Create a plugin factory from the builder's accumulated types.
174
+ * Returns a definePlugin equivalent with no manual type parameters.
175
+ */
176
+ pluginFactory(): <PL extends string = never, PG extends string = never, PAG extends string = never, PRQ extends string = never>(config: {
177
+ id: string;
178
+ install: (world: ECSpresso<Cfg>) => void;
179
+ }) => Plugin<Cfg, EmptyConfig, PL, PG, PAG, PRQ>;
152
180
  /**
153
181
  * Complete the build process and return the built ECSpresso instance
154
182
  */
155
- build(): ECSpresso<C, E, FinalizeBuiltinResources<R, A, S, [AssetGroupNames] extends [never] ? string : AssetGroupNames>, A, S, [
183
+ build(): ECSpresso<FinalizeBuiltinResources<Cfg, [AssetGroupNames] extends [never] ? string : AssetGroupNames>, [
156
184
  Labels
157
185
  ] extends [never] ? string : Labels, [
158
186
  Groups