simple-circuit-engine 0.0.10 → 0.0.12

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 (141) hide show
  1. package/AGENTS.md +13 -7
  2. package/CLAUDE.md +16 -103
  3. package/README.md +8 -5
  4. package/dist/core/index.d.ts +2 -23
  5. package/dist/core/index.js +75 -2000
  6. package/dist/core/setup.d.ts +17 -0
  7. package/dist/core/simulation/CircuitRunner.d.ts +176 -0
  8. package/dist/core/simulation/DirtyTracker.d.ts +87 -0
  9. package/dist/core/simulation/EventQueue.d.ts +68 -0
  10. package/dist/core/simulation/StateManager.d.ts +100 -0
  11. package/dist/core/simulation/behaviors/BehaviorRegistry.d.ts +70 -0
  12. package/dist/core/simulation/behaviors/ComponentBehavior.d.ts +53 -0
  13. package/dist/core/simulation/behaviors/basic/BatteryBehavior.d.ts +14 -0
  14. package/dist/core/simulation/behaviors/basic/ClockBehavior.d.ts +24 -0
  15. package/dist/core/simulation/behaviors/basic/DoubleThrowSwitchBehavior.d.ts +33 -0
  16. package/dist/core/simulation/behaviors/basic/LightbulbBehavior.d.ts +23 -0
  17. package/dist/core/simulation/behaviors/basic/RectangleLEDBehavior.d.ts +24 -0
  18. package/dist/core/simulation/behaviors/basic/RelayBehavior.d.ts +33 -0
  19. package/dist/core/simulation/behaviors/basic/SmallLEDBehavior.d.ts +24 -0
  20. package/dist/core/simulation/behaviors/basic/SwitchBehavior.d.ts +33 -0
  21. package/dist/core/simulation/behaviors/basic/index.d.ts +20 -0
  22. package/dist/core/simulation/behaviors/gates/InverterBehavior.d.ts +29 -0
  23. package/dist/core/simulation/behaviors/gates/Nand4GateBehavior.d.ts +18 -0
  24. package/dist/core/simulation/behaviors/gates/Nand8GateBehavior.d.ts +18 -0
  25. package/dist/core/simulation/behaviors/gates/NandGateBehavior.d.ts +28 -0
  26. package/dist/core/simulation/behaviors/gates/Nor4GateBehavior.d.ts +18 -0
  27. package/dist/core/simulation/behaviors/gates/Nor8GateBehavior.d.ts +18 -0
  28. package/dist/core/simulation/behaviors/gates/NorGateBehavior.d.ts +22 -0
  29. package/dist/core/simulation/behaviors/gates/Xor4GateBehavior.d.ts +18 -0
  30. package/dist/core/simulation/behaviors/gates/Xor8GateBehavior.d.ts +18 -0
  31. package/dist/core/simulation/behaviors/gates/XorGateBehavior.d.ts +22 -0
  32. package/dist/core/simulation/behaviors/gates/index.d.ts +34 -0
  33. package/dist/core/simulation/behaviors/index.d.ts +24 -0
  34. package/dist/core/simulation/behaviors/types.d.ts +101 -0
  35. package/dist/core/simulation/index.d.ts +18 -0
  36. package/dist/core/simulation/states/ComponentState.d.ts +57 -0
  37. package/dist/core/simulation/states/SimulationState.d.ts +46 -0
  38. package/dist/core/simulation/states/basic/BatteryState.d.ts +16 -0
  39. package/dist/core/simulation/states/basic/ClockState.d.ts +16 -0
  40. package/dist/core/simulation/states/basic/DoubleThrowSwitchState.d.ts +21 -0
  41. package/dist/core/simulation/states/basic/LightbulbState.d.ts +21 -0
  42. package/dist/core/simulation/states/basic/RectangleLEDState.d.ts +9 -0
  43. package/dist/core/simulation/states/basic/RelayState.d.ts +25 -0
  44. package/dist/core/simulation/states/basic/SmallLEDState.d.ts +21 -0
  45. package/dist/core/simulation/states/basic/SwitchState.d.ts +25 -0
  46. package/dist/core/simulation/states/gates/InverterState.d.ts +17 -0
  47. package/dist/core/simulation/states/gates/Nand4GateState.d.ts +10 -0
  48. package/dist/core/simulation/states/gates/Nand8GateState.d.ts +10 -0
  49. package/dist/core/simulation/states/gates/NandGateState.d.ts +16 -0
  50. package/dist/core/simulation/states/gates/Nor4GateState.d.ts +10 -0
  51. package/dist/core/simulation/states/gates/Nor8GateState.d.ts +10 -0
  52. package/dist/core/simulation/states/gates/NorGateState.d.ts +10 -0
  53. package/dist/core/simulation/states/gates/Xor4GateState.d.ts +10 -0
  54. package/dist/core/simulation/states/gates/Xor8GateState.d.ts +10 -0
  55. package/dist/core/simulation/states/gates/XorGateState.d.ts +10 -0
  56. package/dist/core/simulation/states/gates/index.d.ts +25 -0
  57. package/dist/core/simulation/states/index.d.ts +26 -0
  58. package/dist/core/simulation/states/types.d.ts +32 -0
  59. package/dist/core/simulation/types.d.ts +155 -0
  60. package/dist/core/topology/Circuit.d.ts +420 -0
  61. package/dist/core/topology/CircuitMetadata.d.ts +24 -0
  62. package/dist/core/topology/CircuitOptions.d.ts +14 -0
  63. package/dist/core/topology/Component.d.ts +152 -0
  64. package/dist/core/topology/ENode.d.ts +200 -0
  65. package/dist/core/topology/Wire.d.ts +130 -0
  66. package/dist/core/topology/delays.d.ts +52 -0
  67. package/dist/core/topology/index.d.ts +14 -0
  68. package/dist/core/topology/types.d.ts +175 -0
  69. package/dist/core/utils/CameraOptions.d.ts +83 -0
  70. package/dist/core/utils/MemoizeDecorator.d.ts +9 -0
  71. package/dist/core/utils/Position.d.ts +166 -0
  72. package/dist/core/utils/Position3D.d.ts +77 -0
  73. package/dist/core/utils/Rotation.d.ts +82 -0
  74. package/dist/core/utils/index.d.ts +24 -0
  75. package/dist/core/utils/types.d.ts +35 -0
  76. package/dist/core-Bjta9Y7_.js +2707 -0
  77. package/dist/core-Bjta9Y7_.js.map +1 -0
  78. package/dist/index.d.ts +13 -6286
  79. package/dist/index.js +120 -100
  80. package/dist/scene/CircuitEngine.d.ts +270 -0
  81. package/dist/scene/index.d.ts +1 -2
  82. package/dist/scene/index.js +44 -38
  83. package/dist/scene/setup.d.ts +18 -0
  84. package/dist/scene/shared/AbstractCircuitController.d.ts +211 -0
  85. package/dist/scene/shared/BranchingPointVisualFactory.d.ts +70 -0
  86. package/dist/scene/shared/EventEmitter.d.ts +92 -0
  87. package/dist/scene/shared/HoverManager.d.ts +151 -0
  88. package/dist/scene/shared/SelectionManager.d.ts +159 -0
  89. package/dist/scene/shared/WireVisualManager.d.ts +242 -0
  90. package/dist/scene/shared/components/ComponentVisualFactory.d.ts +438 -0
  91. package/dist/scene/shared/components/DefaultVisualFactory.d.ts +51 -0
  92. package/dist/scene/shared/components/FactoryRegistry.d.ts +84 -0
  93. package/dist/scene/shared/components/GroupedFactoryRegistry.d.ts +153 -0
  94. package/dist/scene/shared/components/basic/BatteryVisualFactory.d.ts +13 -0
  95. package/dist/scene/shared/components/basic/ClockVisualFactory.d.ts +79 -0
  96. package/dist/scene/shared/components/basic/DoubleThrowSwitchVisualFactory.d.ts +87 -0
  97. package/dist/scene/shared/components/basic/LabelVisualFactory.d.ts +148 -0
  98. package/dist/scene/shared/components/basic/LightbulbVisualFactory.d.ts +72 -0
  99. package/dist/scene/shared/components/basic/RectangleLEDVisualFactory.d.ts +86 -0
  100. package/dist/scene/shared/components/basic/RelayVisualFactory.d.ts +92 -0
  101. package/dist/scene/shared/components/basic/SmallLEDVisualFactory.d.ts +86 -0
  102. package/dist/scene/shared/components/basic/SwitchVisualFactory.d.ts +85 -0
  103. package/dist/scene/shared/components/gates/InverterVisualFactory.d.ts +104 -0
  104. package/dist/scene/shared/components/gates/Nand4GateVisualFactory.d.ts +27 -0
  105. package/dist/scene/shared/components/gates/Nand8GateVisualFactory.d.ts +27 -0
  106. package/dist/scene/shared/components/gates/NandGateVisualFactory.d.ts +101 -0
  107. package/dist/scene/shared/components/gates/Nor4GateVisualFactory.d.ts +27 -0
  108. package/dist/scene/shared/components/gates/Nor8GateVisualFactory.d.ts +27 -0
  109. package/dist/scene/shared/components/gates/NorGateVisualFactory.d.ts +101 -0
  110. package/dist/scene/shared/components/gates/Xor4GateVisualFactory.d.ts +29 -0
  111. package/dist/scene/shared/components/gates/Xor8GateVisualFactory.d.ts +29 -0
  112. package/dist/scene/shared/components/gates/XorGateVisualFactory.d.ts +103 -0
  113. package/dist/scene/shared/components/index.d.ts +29 -0
  114. package/dist/scene/shared/components/types.d.ts +43 -0
  115. package/dist/scene/shared/types.d.ts +476 -0
  116. package/dist/scene/shared/utils/CameraUtils.d.ts +23 -0
  117. package/dist/scene/shared/utils/ColorUtils.d.ts +26 -0
  118. package/dist/scene/shared/utils/ControlsUtils.d.ts +8 -0
  119. package/dist/scene/shared/utils/GeometryUtils.d.ts +261 -0
  120. package/dist/scene/shared/utils/LayerConstants.d.ts +40 -0
  121. package/dist/scene/shared/utils/LightingUtils.d.ts +31 -0
  122. package/dist/scene/shared/utils/MaterialUtils.d.ts +73 -0
  123. package/dist/scene/shared/utils/Options.d.ts +16 -0
  124. package/dist/scene/simulation/CircuitRunnerController.d.ts +227 -0
  125. package/dist/scene/static/CircuitController.d.ts +227 -0
  126. package/dist/scene/static/CircuitWriter.d.ts +146 -0
  127. package/dist/scene/static/PinTooltipWidget.d.ts +26 -0
  128. package/dist/scene/static/tools/BuildTool.d.ts +286 -0
  129. package/dist/scene/static/tools/ComponentPickerWidget.d.ts +82 -0
  130. package/dist/scene/static/tools/ConfigPanelWidget.d.ts +93 -0
  131. package/dist/scene/static/tools/MultiSelectTool.d.ts +265 -0
  132. package/dist/scene-CVsDdySt.js +7357 -0
  133. package/dist/scene-CVsDdySt.js.map +1 -0
  134. package/package.json +24 -25
  135. package/dist/CircuitRunner-DEb7JdNf.js +0 -1809
  136. package/dist/CircuitRunner-DEb7JdNf.js.map +0 -1
  137. package/dist/core/index.js.map +0 -1
  138. package/dist/index.js.map +0 -1
  139. package/dist/scene/index.js.map +0 -1
  140. package/dist/setup-AB1vFiis.js +0 -9918
  141. package/dist/setup-AB1vFiis.js.map +0 -1
@@ -0,0 +1,17 @@
1
+ import { BehaviorRegistry } from './simulation';
2
+ /**
3
+ * Register all basic component behaviors in the given registry
4
+ * Basic components are : Battery, Lightbulb, RectangleLED, Relay, SmallLED, Switch, double switch
5
+ * @public
6
+ * @param registry
7
+ * @return the input behavior registry for chaining
8
+ */
9
+ export declare function registerBasicComponentsBehaviors(registry: BehaviorRegistry): BehaviorRegistry;
10
+ /**
11
+ * Register all gates component behaviors in the given registry
12
+ * Gates components are : Inverter, NandGate (2,4,8), NorGate (2,4,8), XorGate (2,4,8)
13
+ * @public
14
+ * @param registry
15
+ * @return the input behavior registry for chaining
16
+ */
17
+ export declare function registerGatesComponentsBehaviors(registry: BehaviorRegistry): BehaviorRegistry;
@@ -0,0 +1,176 @@
1
+ import { Circuit } from '../topology/Circuit';
2
+ import { ComponentState } from './states/ComponentState.js';
3
+ import { SimulationState } from './states/SimulationState';
4
+ import { StateManager } from './StateManager.js';
5
+ import { EventQueue } from './EventQueue.js';
6
+ import { DirtyTracker } from './DirtyTracker.js';
7
+ import { BehaviorRegistry } from './behaviors';
8
+ import { INodeElectricalState } from './states';
9
+ import { IUserCommand, IRunnerOptions, IRunnerResult } from './types';
10
+ import { UUID } from '../utils/types';
11
+ /**
12
+ * Main circuit simulation controller.
13
+ * Manages discrete-time simulation with event-driven state propagation.
14
+ *
15
+ * Features:
16
+ * - Boolean electrical state (voltage/current present or not)
17
+ * - Event-driven delayed transitions
18
+ * - Dirty tracking for optimization
19
+ * - Configurable history storage
20
+ * - Registry-based component behaviors
21
+ *
22
+ * @public
23
+ */
24
+ export declare class CircuitRunner {
25
+ readonly circuit: Circuit;
26
+ readonly stateManager: StateManager;
27
+ readonly eventQueue: EventQueue;
28
+ readonly commands: Map<UUID, IUserCommand>;
29
+ readonly dirtyTracker: DirtyTracker;
30
+ readonly behaviorRegistry: BehaviorRegistry;
31
+ /**
32
+ * Create a new circuit simulation runner.
33
+ *
34
+ * @param circuit - The circuit topology to simulate
35
+ * @param behaviorRegistry - Registry of component behaviors
36
+ * @param options - Simulation options (history settings)
37
+ */
38
+ constructor(circuit: Circuit, behaviorRegistry: BehaviorRegistry, options?: IRunnerOptions);
39
+ /**
40
+ * Execute one simulation tick.
41
+ * Process scheduled events, update state (electrical propagation), process user commands and advance tick.
42
+ *
43
+ * @returns the result of the tick execution
44
+ */
45
+ tick(): IRunnerResult;
46
+ /**
47
+ * Execute multiple simulation ticks.
48
+ *
49
+ * @param count - Number of ticks to execute
50
+ * @returns an array of IRunnerResult for each tick executed
51
+ */
52
+ tickN(count: number): IRunnerResult[];
53
+ /**
54
+ * Reset simulation to tick 0.
55
+ * Clears all state, history, and scheduled events.
56
+ */
57
+ reset(): void;
58
+ /**
59
+ * Get current simulation tick number.
60
+ *
61
+ * @returns Current tick
62
+ */
63
+ getCurrentTick(): number;
64
+ /**
65
+ * Get current simulation state snapshot.
66
+ *
67
+ * @returns Current state (readonly)
68
+ */
69
+ getCurrentState(): SimulationState;
70
+ /**
71
+ * Get electrical state of a specific ENode.
72
+ *
73
+ * @param enodeId - UUID of the ENode
74
+ * @returns Electrical state, or undefined if not found
75
+ */
76
+ getEnodeState(enodeId: UUID): INodeElectricalState | undefined;
77
+ /**
78
+ * Get electrical state of a specific Wire.
79
+ *
80
+ * @param wireId - UUID of the Wire
81
+ * @returns Electrical state, or undefined if not found
82
+ */
83
+ getWireState(wireId: UUID): INodeElectricalState | undefined;
84
+ /**
85
+ * Get component state for a specific component.
86
+ *
87
+ * @param componentId - UUID of the component
88
+ * @returns Component state, or undefined if not found
89
+ */
90
+ getComponentState(componentId: UUID): ComponentState | undefined;
91
+ /**
92
+ * Get historical state at a specific tick.
93
+ * Only works if history is enabled.
94
+ *
95
+ * @param tick - Tick number to retrieve
96
+ * @returns Historical state, or undefined if not available
97
+ */
98
+ getStateAtTick(tick: number): SimulationState | undefined;
99
+ /**
100
+ * Check if a component is registered in behavior registry.
101
+ *
102
+ * @param componentType - Component type to check
103
+ * @returns True if behavior is registered
104
+ */
105
+ hasBehavior(componentType: string): boolean;
106
+ /**
107
+ * Submit a user command to execute at the next tick.
108
+ * only one command per component per tick is allowed.
109
+ * Subsequent commands for the same component at this tick will be discarded.
110
+ *
111
+ * @param command - User command to submit
112
+ */
113
+ submitCommand(command: IUserCommand): boolean;
114
+ /**
115
+ * Process all scheduled user commands.
116
+ * Mark changed components as Dirty and enqueue consequent scheduled events
117
+ * Finally clears command queue after processing.
118
+ *
119
+ * @returns Array of IBehaviorResult for each processed command
120
+ */
121
+ private processCommands;
122
+ /**
123
+ * Helper function to extract initializationOrder from component config.
124
+ * Returns numeric order value, with empty string or null defaulting to 0.
125
+ *
126
+ * @param config - Component configuration map
127
+ * @returns Order value (lower = processed first)
128
+ */
129
+ private getInitializationOrder;
130
+ /**
131
+ * Initialize simulation state for all components.
132
+ * Called on construction and reset.
133
+ *
134
+ * Uses order-based initialization to resolve feedback loops:
135
+ * 1. Components are grouped by initializationOrder (higher = processed LAST)
136
+ * 2. Within each group, components are sorted by UUID (ascending) for determinism
137
+ * 3. Conductivity is propagated after each component
138
+ *
139
+ * In feedback circuits, the component processed LAST "wins" because earlier
140
+ * components react to the initial symmetric state and open, while later
141
+ * components see the updated (asymmetric) state and stay closed.
142
+ */
143
+ private initializeState;
144
+ /**
145
+ * Core method that orchestrates nodes, wires and components state updates
146
+ * enqueue resulting events and update dirty tracker accordingly
147
+ * @param targetTick - Tick at which to perform the update
148
+ */
149
+ private updateState;
150
+ /**
151
+ * runs BFS (Breadth First Search) on voltage and current conductivity
152
+ * to propagate voltage/current conductivity
153
+ * and update enodes/wires electrical states throughout the circuit
154
+ * update is performed in place and updated nodes and wires returned
155
+ */
156
+ private propagateConductivity;
157
+ /**
158
+ * given a conductivity conductivityType and a set of seed nodes, compute all reachable nodes and wires
159
+ * depends on componentStates to determine if conductivity is allowed through components
160
+ * this method doesn't mutate any state, it's a pure function
161
+ * @param conductivityType
162
+ * @param seeds
163
+ * @param componentStates
164
+ */
165
+ private computeReachability;
166
+ /**
167
+ * Fire ready events and update current state accordingly
168
+ * eventual subsequent events are enqueued
169
+ *
170
+ * @param targetTick - Tick at which to process events
171
+ * @param events - Events to apply
172
+ * @param state - Current simulation state
173
+ * @param targetTick - Target tick for event processing
174
+ */
175
+ private applyReadyEvents;
176
+ }
@@ -0,0 +1,87 @@
1
+ import { IDirtyElements } from './types';
2
+ import { UUID } from '../utils/types';
3
+ /**
4
+ * Tracks per-element changes for optimized state propagation.
5
+ * Provides granular dirty tracking at component/wire/enode level.
6
+ *
7
+ * Used to avoid re-processing unchanged elements during simulation ticks.
8
+ *
9
+ * @public
10
+ */
11
+ export declare class DirtyTracker {
12
+ private dirtyComponents;
13
+ private dirtyWires;
14
+ private dirtyEnodes;
15
+ /**
16
+ * Create a new dirty tracker with no marked elements.
17
+ */
18
+ constructor();
19
+ /**
20
+ * Mark a component as having changed state this tick.
21
+ *
22
+ * @param componentId - UUID of the component
23
+ */
24
+ markComponentDirty(componentId: UUID): void;
25
+ /**
26
+ * Mark a wire as having changed electrical state this tick.
27
+ *
28
+ * @param wireId - UUID of the wire
29
+ */
30
+ markWireDirty(wireId: UUID): void;
31
+ /**
32
+ * Mark an ENode as having changed electrical state this tick.
33
+ *
34
+ * @param enodeId - UUID of the ENode
35
+ */
36
+ markEnodeDirty(enodeId: UUID): void;
37
+ /**
38
+ * Set the entire set of dirty components. Should be only used at CircuitRunner initialization.
39
+ * @param componentIds
40
+ */
41
+ setDirtyComponents(componentIds: Set<UUID>): void;
42
+ /**
43
+ * Set the entire set of dirty components. Should be only used at CircuitRunner initialization.
44
+ * @param enodeIds
45
+ */
46
+ setDirtyEnodes(enodeIds: Set<UUID>): void;
47
+ /**
48
+ * Set the entire set of dirty components. Should be only used at CircuitRunner initialization.
49
+ * @param wireIds
50
+ */
51
+ setDirtyWires(wireIds: Set<UUID>): void;
52
+ /**
53
+ * Get all dirty elements and clear the tracker.
54
+ * This is typically called at the end of a tick to collect changes.
55
+ *
56
+ * @returns Object containing sets of dirty component/wire/enode UUIDs
57
+ */
58
+ getDirtyElements(): IDirtyElements;
59
+ /**
60
+ * Check if any elements are marked dirty.
61
+ *
62
+ * @returns True if at least one element is dirty
63
+ */
64
+ hasDirtyElements(): boolean;
65
+ /**
66
+ * Clear all dirty markers without returning them.
67
+ */
68
+ clear(): void;
69
+ /**
70
+ * Get current count of dirty components (for debugging/metrics).
71
+ *
72
+ * @returns Number of dirty components
73
+ */
74
+ getDirtyComponentCount(): number;
75
+ /**
76
+ * Get current count of dirty wires (for debugging/metrics).
77
+ *
78
+ * @returns Number of dirty wires
79
+ */
80
+ getDirtyWireCount(): number;
81
+ /**
82
+ * Get current count of dirty enodes (for debugging/metrics).
83
+ *
84
+ * @returns Number of dirty enodes
85
+ */
86
+ getDirtyEnodeCount(): number;
87
+ }
@@ -0,0 +1,68 @@
1
+ import { IScheduledEvent } from './types';
2
+ /**
3
+ * Min-heap priority queue for scheduling future component transitions.
4
+ * Events are ordered by readyAtTick (earliest first).
5
+ * Events with same readyAtTick are returned in FIFO order (by scheduledAtTick).
6
+ *
7
+ * @public
8
+ */
9
+ export declare class EventQueue {
10
+ private heap;
11
+ /**
12
+ * Create a new empty event queue.
13
+ */
14
+ constructor();
15
+ /**
16
+ * Schedule a future event.
17
+ * Inserted with O(log N) complexity using heap operations.
18
+ *
19
+ * @param event - Event to schedule
20
+ */
21
+ schedule(event: IScheduledEvent): void;
22
+ /**
23
+ * Get all events ready to fire at or before current tick.
24
+ * Returns events in FIFO order for same readyAtTick.
25
+ * Removes returned events from the queue.
26
+ *
27
+ * @param currentTick - Current simulation tick
28
+ * @returns Array of ready events (removed from queue)
29
+ */
30
+ getReadyEvents(currentTick: number): IScheduledEvent[];
31
+ /**
32
+ * Check if any events are pending.
33
+ *
34
+ * @returns True if queue contains events
35
+ */
36
+ hasEvents(): boolean;
37
+ /**
38
+ * Clear all pending events.
39
+ */
40
+ clear(): void;
41
+ /**
42
+ * Schedule multiple events at once, optionally cancelling pending events for specific targets.
43
+ * More efficient than individual schedule() + removeEventsForTarget() calls:
44
+ * single filter pass for all cancellations, batch push, single heap rebuild.
45
+ *
46
+ * @param events - Events to schedule
47
+ * @param cancelTargets - Target IDs whose pending events should be removed before inserting
48
+ */
49
+ scheduleMany(events: ReadonlyArray<IScheduledEvent>, cancelTargets?: ReadonlySet<string>): void;
50
+ /**
51
+ * Remove all pending events targeting a specific component.
52
+ * Used when a behavior signals shouldCancelPending (e.g., Vcc loss, input change during transition).
53
+ *
54
+ * @param targetId - UUID of the component whose events should be removed
55
+ * @returns Number of events removed
56
+ */
57
+ removeEventsForTarget(targetId: string): number;
58
+ /**
59
+ * Get number of pending events.
60
+ *
61
+ * @returns Event count
62
+ */
63
+ size(): number;
64
+ private rebuildHeap;
65
+ private bubbleUp;
66
+ private bubbleDown;
67
+ private extractMin;
68
+ }
@@ -0,0 +1,100 @@
1
+ import { SimulationState } from './states/SimulationState';
2
+ /**
3
+ * Manages current simulation state and historical state storage.
4
+ * Uses a circular buffer for efficient memory-bounded history.
5
+ *
6
+ * @public
7
+ */
8
+ export declare class StateManager {
9
+ private currentState;
10
+ private history;
11
+ private readonly historyEnabled;
12
+ private readonly historyLimit;
13
+ private historyWriteIndex;
14
+ /**
15
+ * Create a new state controllerType.
16
+ *
17
+ * @param enableHistory - Whether to store state history (default: false)
18
+ * @param historyLimit - Maximum number of historical states to keep (default: 1000)
19
+ */
20
+ constructor(enableHistory?: boolean, historyLimit?: number);
21
+ /**
22
+ * Get the current simulation state.
23
+ *
24
+ * @returns Current state (mutable for simulation controller use)
25
+ */
26
+ getCurrentState(): SimulationState;
27
+ /**
28
+ * Get current tick number.
29
+ *
30
+ * @returns Current simulation tick
31
+ */
32
+ getCurrentTick(): number;
33
+ /**
34
+ * Advance to next tick, optionally saving current state to history.
35
+ * Creates a new SimulationState for the next tick.
36
+ *
37
+ * @returns New current state for the next tick
38
+ */
39
+ advanceToNextTick(): SimulationState;
40
+ /**
41
+ * Get a historical state by tick number.
42
+ * Only works if history is enabled.
43
+ *
44
+ * @param tick - Tick number to retrieve
45
+ * @returns State at that tick, or undefined if not available
46
+ */
47
+ getStateAtTick(tick: number): SimulationState | undefined;
48
+ /**
49
+ * Get all available historical states.
50
+ * Returns empty array if history is disabled.
51
+ *
52
+ * @returns Array of historical states, sorted by tick (oldest first)
53
+ */
54
+ getHistory(): ReadonlyArray<SimulationState>;
55
+ /**
56
+ * Get the oldest tick number available in history.
57
+ *
58
+ * @returns Oldest tick number, or undefined if no history
59
+ */
60
+ getOldestTick(): number | undefined;
61
+ /**
62
+ * Get the newest tick number in history (not including current tick).
63
+ *
64
+ * @returns Newest historical tick, or undefined if no history
65
+ */
66
+ getNewestHistoricalTick(): number | undefined;
67
+ /**
68
+ * Clear all history.
69
+ */
70
+ clearHistory(): void;
71
+ /**
72
+ * Reset to tick 0, clearing current state and all history.
73
+ */
74
+ reset(): void;
75
+ /**
76
+ * Check if history tracking is enabled.
77
+ *
78
+ * @returns True if history is enabled
79
+ */
80
+ isHistoryEnabled(): boolean;
81
+ /**
82
+ * Get the configured history limit.
83
+ *
84
+ * @returns Maximum number of historical states
85
+ */
86
+ getHistoryLimit(): number;
87
+ /**
88
+ * Get current history size.
89
+ *
90
+ * @returns Number of states in history
91
+ */
92
+ getHistorySize(): number;
93
+ /**
94
+ * Save a state to history using circular buffer.
95
+ * Private helper for advanceToNextTick.
96
+ *
97
+ * @param state - State to save
98
+ */
99
+ private saveToHistory;
100
+ }
@@ -0,0 +1,70 @@
1
+ import { IComponentBehavior } from './types';
2
+ /**
3
+ * Registry for component behavior implementations.
4
+ * Maps component types to their behavior handlers.
5
+ *
6
+ * This allows the simulation controller to be extended with new component types
7
+ * without modifying core simulation logic.
8
+ *
9
+ * @public
10
+ */
11
+ export declare class BehaviorRegistry {
12
+ private behaviors;
13
+ /**
14
+ * Create a new empty behavior registry.
15
+ */
16
+ constructor();
17
+ /**
18
+ * Register a behavior for a component type.
19
+ * Overwrites any existing behavior for the same type.
20
+ *
21
+ * @param behavior - The component behavior to register
22
+ * @throws TypeError if behavior is null/undefined or componentType is empty
23
+ * @returns The registry instance for chaining
24
+ */
25
+ register(behavior: IComponentBehavior): BehaviorRegistry;
26
+ /**
27
+ * Register multiple behaviors at once.
28
+ * Convenience method for bulk registration.
29
+ *
30
+ * @param behaviors - Array of behaviors to register
31
+ */
32
+ registerAll(behaviors: IComponentBehavior[]): void;
33
+ /**
34
+ * Get the behavior for a component type.
35
+ *
36
+ * @param componentType - Type identifier (e.g., "battery", "led")
37
+ * @returns The registered behavior, or undefined if not found
38
+ */
39
+ get(componentType: string): IComponentBehavior | undefined;
40
+ /**
41
+ * Check if a behavior is registered for a component type.
42
+ *
43
+ * @param componentType - Type identifier to check
44
+ * @returns True if behavior is registered
45
+ */
46
+ has(componentType: string): boolean;
47
+ /**
48
+ * Unregister a behavior for a component type.
49
+ *
50
+ * @param componentType - Type identifier to unregister
51
+ * @returns True if behavior was found and removed
52
+ */
53
+ unregister(componentType: string): boolean;
54
+ /**
55
+ * Clear all registered behaviors.
56
+ */
57
+ clear(): void;
58
+ /**
59
+ * Get all registered component types.
60
+ *
61
+ * @returns Array of component type identifiers
62
+ */
63
+ getRegisteredTypes(): string[];
64
+ /**
65
+ * Get count of registered behaviors.
66
+ *
67
+ * @returns Number of registered behaviors
68
+ */
69
+ size(): number;
70
+ }
@@ -0,0 +1,53 @@
1
+ import { Component } from '../../topology/Component';
2
+ import { ComponentState } from '../states/ComponentState.js';
3
+ import { IScheduledEvent, IUserCommand } from '../types';
4
+ import { IBehaviorResult } from './types';
5
+ import { INodeElectricalState } from '../states/types';
6
+ import { UUID } from '../../utils/types';
7
+ import { ComponentType, ENodeSourceType, IComponentTypeMetadata } from '../../topology/types';
8
+ /**
9
+ * to factorize default implementations in component behaviors
10
+ */
11
+ export declare abstract class ComponentBehaviorMixin {
12
+ /**
13
+ * Component type this behavior handles (e.g., "battery", "led", "switch").
14
+ * Used as the key in BehaviorRegistry.
15
+ */
16
+ protected readonly _componentType: ComponentType;
17
+ constructor(componentType: ComponentType);
18
+ get componentType(): ComponentType;
19
+ protected get typeMetadata(): IComponentTypeMetadata;
20
+ protected getPinStates(component: Component, nodeStates: ReadonlyMap<UUID, INodeElectricalState>): Map<string, INodeElectricalState>;
21
+ protected getChangedPins(newPinStates: Map<string, INodeElectricalState>, prevPinStates: Map<string, INodeElectricalState>): Set<string>;
22
+ /**
23
+ * Default: no custom onStart behavior
24
+ * @param _component
25
+ * @param _componentState
26
+ */
27
+ onStart(_component: Component, _componentState: ComponentState): IBehaviorResult | null;
28
+ /**
29
+ * Default: nothing happens
30
+ * @param _component
31
+ * @param componentState
32
+ * @param _nodeStates
33
+ * @param _targetTick
34
+ */
35
+ onPinsChange(_component: Component, componentState: ComponentState, _nodeStates: ReadonlyMap<UUID, INodeElectricalState>, _targetTick: number): IBehaviorResult;
36
+ /**
37
+ * Default: no conductivity between pins
38
+ * @param _component
39
+ * @param _state
40
+ * @param _conductivityType
41
+ * @param _pinId
42
+ * @param _otherPinId
43
+ */
44
+ allowConductivity(_component: Component, _state: ComponentState, _conductivityType: ENodeSourceType, _pinId: string, _otherPinId: string): boolean;
45
+ onUserCommand(_component: Component, state: ComponentState, _command: IUserCommand): IBehaviorResult;
46
+ onEventFiring(_component: Component, state: ComponentState, _event: IScheduledEvent): IBehaviorResult;
47
+ }
48
+ /**
49
+ * Get the transition span from component config.
50
+ * @param config - Component config map
51
+ * @returns Number of ticks for transition (minimum 1)
52
+ */
53
+ export declare function getTransitionSpan(config: Map<string, string>): number;
@@ -0,0 +1,14 @@
1
+ import { Component } from '../../../topology/Component';
2
+ import { ComponentBehaviorMixin } from '../ComponentBehavior';
3
+ import { ComponentState } from '../../states/ComponentState';
4
+ import { IComponentBehavior } from '../types';
5
+ export declare class BatteryBehavior extends ComponentBehaviorMixin implements IComponentBehavior {
6
+ constructor();
7
+ /**
8
+ * Create initial state for a battery.
9
+ *
10
+ * @param component - The Battery component
11
+ * @returns Battery Initial state (always active and delivering voltage)
12
+ */
13
+ createInitialState(component: Component): ComponentState;
14
+ }
@@ -0,0 +1,24 @@
1
+ import { Component } from '../../../topology/Component';
2
+ import { ComponentBehaviorMixin } from '../ComponentBehavior';
3
+ import { ComponentState } from '../../states/ComponentState';
4
+ import { IComponentBehavior, IBehaviorResult } from '../types';
5
+ import { ENodeSourceType } from '../../../topology/types';
6
+ import { IScheduledEvent } from '../../types';
7
+ export declare class ClockBehavior extends ComponentBehaviorMixin implements IComponentBehavior {
8
+ constructor();
9
+ /**
10
+ * Create initial state for a Clock.
11
+ *
12
+ * @param component - The Clock component
13
+ * @returns Clock Initial state (needle rotation)
14
+ */
15
+ createInitialState(component: Component): ComponentState;
16
+ allowConductivity(component: Component, state: ComponentState, _conductivityType: ENodeSourceType, pinId: string, otherPinId: string): boolean;
17
+ /**
18
+ * Clock onStart allows to bootstrap cycling
19
+ * @param component
20
+ * @param state
21
+ */
22
+ onStart(component: Component, state: ComponentState): IBehaviorResult | null;
23
+ onEventFiring(component: Component, state: ComponentState, event: IScheduledEvent): IBehaviorResult;
24
+ }
@@ -0,0 +1,33 @@
1
+ import { Component } from '../../../topology/Component';
2
+ import { ComponentState, INodeElectricalState } from '../../states';
3
+ import { IScheduledEvent, IUserCommand } from '../../types';
4
+ import { ComponentBehaviorMixin } from '../ComponentBehavior';
5
+ import { IBehaviorResult, IComponentBehavior } from '../types';
6
+ import { ENodeSourceType } from '../../../topology/types';
7
+ import { UUID } from '../../../utils';
8
+ /**
9
+ * Behavior implementation for switches components.
10
+ *
11
+ * @public
12
+ */
13
+ export declare class DoubleThrowSwitchBehavior extends ComponentBehaviorMixin implements IComponentBehavior {
14
+ constructor();
15
+ /**
16
+ * Create initial state for a double throw switch (SPDT).
17
+ *
18
+ * @param component - The double Switch component
19
+ * @returns double Switch Initial state (input1 by default)
20
+ */
21
+ createInitialState(component: Component): ComponentState;
22
+ allowConductivity(component: Component, state: ComponentState, _conductivityType: ENodeSourceType, pinId: string, otherPinId: string): boolean;
23
+ /**
24
+ * used for contactor color change
25
+ * @param component
26
+ * @param state
27
+ * @param nodeStates
28
+ * @param _targetTick
29
+ */
30
+ onPinsChange(component: Component, state: ComponentState, nodeStates: ReadonlyMap<UUID, INodeElectricalState>, _targetTick: number): IBehaviorResult;
31
+ onUserCommand(component: Component, state: ComponentState, command: IUserCommand): IBehaviorResult;
32
+ onEventFiring(_component: Component, state: ComponentState, event: IScheduledEvent): IBehaviorResult;
33
+ }
@@ -0,0 +1,23 @@
1
+ import { Component } from '../../../topology/Component';
2
+ import { ComponentState } from '../../states/ComponentState';
3
+ import { BipolarLightEmitterBehaviorMixin } from './index';
4
+ import { IBehaviorResult, IComponentBehavior } from '../types';
5
+ import { INodeElectricalState } from '../../states';
6
+ import { UUID } from '../../../utils/types';
7
+ export declare class LightbulbBehavior extends BipolarLightEmitterBehaviorMixin implements IComponentBehavior {
8
+ constructor();
9
+ /**
10
+ * Create initial state for a lightbulb.
11
+ *
12
+ * @param component - The lightbulb component
13
+ * @returns lightbulbInitial state (always active and delivering voltage)
14
+ */
15
+ createInitialState(component: Component): ComponentState;
16
+ /**
17
+ * @param component
18
+ * @param state
19
+ * @param nodeStates
20
+ * @param targetTick
21
+ */
22
+ onPinsChange(component: Component, state: ComponentState, nodeStates: ReadonlyMap<UUID, INodeElectricalState>, targetTick: number): IBehaviorResult;
23
+ }