@typecad/simulator 0.1.0-alpha.1

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 (42) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +148 -0
  3. package/dist/board/board-sim.d.ts +52 -0
  4. package/dist/board/board-sim.js +188 -0
  5. package/dist/board/from-definition.d.ts +43 -0
  6. package/dist/board/from-definition.js +82 -0
  7. package/dist/bus/i2c-sim.d.ts +61 -0
  8. package/dist/bus/i2c-sim.js +155 -0
  9. package/dist/bus/serial-sim.d.ts +71 -0
  10. package/dist/bus/serial-sim.js +241 -0
  11. package/dist/bus/spi-sim.d.ts +65 -0
  12. package/dist/bus/spi-sim.js +202 -0
  13. package/dist/contracts.d.ts +223 -0
  14. package/dist/contracts.js +87 -0
  15. package/dist/gpio/analog-pin-sim.d.ts +40 -0
  16. package/dist/gpio/analog-pin-sim.js +75 -0
  17. package/dist/gpio/digital-pin-sim.d.ts +68 -0
  18. package/dist/gpio/digital-pin-sim.js +172 -0
  19. package/dist/gpio/interrupt-sim.d.ts +69 -0
  20. package/dist/gpio/interrupt-sim.js +118 -0
  21. package/dist/gpio/pwm-pin-sim.d.ts +41 -0
  22. package/dist/gpio/pwm-pin-sim.js +85 -0
  23. package/dist/helpers.d.ts +40 -0
  24. package/dist/helpers.js +57 -0
  25. package/dist/index.d.ts +18 -0
  26. package/dist/index.js +21 -0
  27. package/dist/types.d.ts +92 -0
  28. package/dist/types.js +4 -0
  29. package/package.json +62 -0
  30. package/src/board/board-sim.ts +208 -0
  31. package/src/board/from-definition.ts +91 -0
  32. package/src/bus/i2c-sim.ts +212 -0
  33. package/src/bus/serial-sim.ts +280 -0
  34. package/src/bus/spi-sim.ts +269 -0
  35. package/src/contracts.ts +330 -0
  36. package/src/gpio/analog-pin-sim.ts +91 -0
  37. package/src/gpio/digital-pin-sim.ts +234 -0
  38. package/src/gpio/interrupt-sim.ts +151 -0
  39. package/src/gpio/pwm-pin-sim.ts +103 -0
  40. package/src/helpers.ts +100 -0
  41. package/src/index.ts +59 -0
  42. package/src/types.ts +104 -0
@@ -0,0 +1,172 @@
1
+ // ---------------------------------------------------------------------------
2
+ // @typecad/simulator — Simulated digital pin
3
+ // ---------------------------------------------------------------------------
4
+ import { PinMode } from '@typecad/hal';
5
+ /**
6
+ * Convert a DigitalValue to a plain 0/1 number.
7
+ */
8
+ function toBitValue(value) {
9
+ return value ? 1 : 0;
10
+ }
11
+ /**
12
+ * Simulated digital pin that tracks state transitions.
13
+ */
14
+ /** Default capability flags for a digital pin. */
15
+ const DEFAULT_DIGITAL_CAPS = {
16
+ digitalInput: true,
17
+ digitalOutput: true,
18
+ analogInput: false,
19
+ analogOutput: false,
20
+ pwm: false,
21
+ interrupt: false,
22
+ pullUp: true,
23
+ pullDown: false,
24
+ touch: false,
25
+ openDrain: false,
26
+ };
27
+ export class SimDigitalPin {
28
+ constructor(pinNum, caps) {
29
+ this._value = 0;
30
+ this._pinMode = PinMode.OUTPUT;
31
+ this._history = [];
32
+ this._startTime = Date.now();
33
+ this.number = pinNum;
34
+ this.gpio = pinNum;
35
+ this.capabilities = { ...DEFAULT_DIGITAL_CAPS, ...caps };
36
+ }
37
+ // --- BasePin ---
38
+ getMode() {
39
+ return this._pinMode;
40
+ }
41
+ setMode(mode) {
42
+ this._pinMode = mode;
43
+ }
44
+ has(capability) {
45
+ return this.capabilities[capability];
46
+ }
47
+ // --- Pin configuration ---
48
+ inputPullUp() {
49
+ this._pinMode = PinMode.INPUT_PULLUP;
50
+ this._setBitValue(1);
51
+ }
52
+ inputPullDown() {
53
+ this._pinMode = PinMode.INPUT_PULLDOWN;
54
+ this._setBitValue(0);
55
+ }
56
+ outputOpenDrain(initial) {
57
+ this._pinMode = PinMode.OUTPUT_OPEN_DRAIN;
58
+ if (initial !== undefined) {
59
+ this._setBitValue(toBitValue(initial));
60
+ }
61
+ }
62
+ // --- Fluent mode conversion ---
63
+ asOutput(initial) {
64
+ this._pinMode = PinMode.OUTPUT;
65
+ if (initial !== undefined) {
66
+ this._setBitValue(toBitValue(initial));
67
+ }
68
+ return this;
69
+ }
70
+ asInput() {
71
+ this._pinMode = PinMode.INPUT;
72
+ return this;
73
+ }
74
+ asInputPullUp() {
75
+ this.inputPullUp();
76
+ return this;
77
+ }
78
+ // --- IDigitalInput ---
79
+ read() {
80
+ return this._value === 1;
81
+ }
82
+ isHigh() {
83
+ return this._value === 1;
84
+ }
85
+ isLow() {
86
+ return this._value === 0;
87
+ }
88
+ async waitForRising(_timeout) {
89
+ // In simulation, this resolves immediately.
90
+ // Tests should use injectValue() + explicit assertions instead.
91
+ }
92
+ async waitForFalling(_timeout) {
93
+ // In simulation, this resolves immediately.
94
+ }
95
+ // --- IDigitalOutput ---
96
+ write(value) {
97
+ this._setBitValue(toBitValue(value));
98
+ }
99
+ high() {
100
+ this._setBitValue(1);
101
+ }
102
+ low() {
103
+ this._setBitValue(0);
104
+ }
105
+ toggle() {
106
+ this._setBitValue(this._value === 1 ? 0 : 1);
107
+ }
108
+ pulse(_duration) {
109
+ // In simulation the pulse duration is not awaited, so a pulse produces no
110
+ // observable transition — leave both pin state and history unchanged.
111
+ }
112
+ tone(_frequency) {
113
+ return {
114
+ for(_duration) {
115
+ // No-op in simulation
116
+ },
117
+ };
118
+ }
119
+ noTone() {
120
+ // No-op in simulation
121
+ }
122
+ stop() {
123
+ this.noTone();
124
+ }
125
+ // --- Simulation helpers ---
126
+ /**
127
+ * Inject a value into this pin (simulates external signal).
128
+ * Use this in tests to simulate button presses, sensor triggers, etc.
129
+ */
130
+ injectValue(value) {
131
+ this._setBitValue(value & 1);
132
+ }
133
+ /**
134
+ * Get the history of all state changes on this pin.
135
+ */
136
+ getHistory() {
137
+ return this._history;
138
+ }
139
+ /**
140
+ * Clear the state change history.
141
+ */
142
+ clearHistory() {
143
+ this._history = [];
144
+ }
145
+ /**
146
+ * Get the current value as a plain number (0 or 1).
147
+ */
148
+ getBitValue() {
149
+ return this._value;
150
+ }
151
+ /**
152
+ * Reset the pin to its initial state.
153
+ */
154
+ reset() {
155
+ this._value = 0;
156
+ this._pinMode = PinMode.OUTPUT;
157
+ this._history = [];
158
+ this._startTime = Date.now();
159
+ }
160
+ // --- Internal ---
161
+ _setBitValue(newValue) {
162
+ const oldValue = this._value;
163
+ this._value = newValue & 1;
164
+ if (oldValue !== this._value) {
165
+ this._history.push({
166
+ timestamp: Date.now() - this._startTime,
167
+ from: oldValue,
168
+ to: this._value,
169
+ });
170
+ }
171
+ }
172
+ }
@@ -0,0 +1,69 @@
1
+ import type { InterruptPin, InterruptOptions } from '../contracts.js';
2
+ import type { InterruptHandler } from '@typecad/hal';
3
+ import { SimDigitalPin } from './digital-pin-sim.js';
4
+ type InterruptMode = 'rising' | 'falling' | 'change';
5
+ /**
6
+ * Tracks interrupt firings for test assertions.
7
+ */
8
+ export interface InterruptEvent {
9
+ /** Timestamp (ms since simulation start) */
10
+ timestamp: number;
11
+ /** The trigger mode */
12
+ mode: InterruptMode;
13
+ /** The pin value at time of interrupt */
14
+ pinValue: number;
15
+ }
16
+ /**
17
+ * Simulated interrupt controller for a single pin.
18
+ *
19
+ * Extends SimDigitalPin with interrupt capabilities.
20
+ * Tests can fire interrupts manually via `fireInterrupt()` and verify
21
+ * that handlers were called with the correct arguments.
22
+ */
23
+ export declare class SimInterruptPin extends SimDigitalPin implements InterruptPin {
24
+ private _handlers;
25
+ private _debounceMs;
26
+ private _events;
27
+ constructor(pinNum: number);
28
+ onRising(handler: InterruptHandler, options?: InterruptOptions): void;
29
+ onFalling(handler: InterruptHandler, options?: InterruptOptions): void;
30
+ onChange(handler: InterruptHandler, options?: InterruptOptions): void;
31
+ offInterrupts(): void;
32
+ /** Remove the rising-edge handler. */
33
+ offRising(): void;
34
+ /** Remove the falling-edge handler. */
35
+ offFalling(): void;
36
+ /** Remove all interrupt handlers. */
37
+ offAll(): void;
38
+ /** Check if any interrupt handlers are registered. */
39
+ hasInterrupt(): boolean;
40
+ /**
41
+ * Fire an interrupt manually from test code.
42
+ * @param mode - The interrupt mode to fire
43
+ * @param pinValue - The current pin value (for event logging)
44
+ */
45
+ fireInterrupt(mode: InterruptMode, pinValue?: number): void;
46
+ /**
47
+ * Simulate a pin value transition, automatically firing the appropriate interrupts.
48
+ * @param from - Previous pin value (0 or 1)
49
+ * @param to - New pin value (0 or 1)
50
+ */
51
+ simulateTransition(from: number, to: number): void;
52
+ /**
53
+ * Get all recorded interrupt events.
54
+ */
55
+ getEvents(): readonly InterruptEvent[];
56
+ /**
57
+ * Clear interrupt event history.
58
+ */
59
+ clearEvents(): void;
60
+ /**
61
+ * Get the configured debounce time.
62
+ */
63
+ getDebounceMs(): number;
64
+ /**
65
+ * Reset to initial state.
66
+ */
67
+ reset(): void;
68
+ }
69
+ export {};
@@ -0,0 +1,118 @@
1
+ // ---------------------------------------------------------------------------
2
+ // @typecad/simulator — Interrupt simulation
3
+ // ---------------------------------------------------------------------------
4
+ import { SimDigitalPin } from './digital-pin-sim.js';
5
+ /**
6
+ * Simulated interrupt controller for a single pin.
7
+ *
8
+ * Extends SimDigitalPin with interrupt capabilities.
9
+ * Tests can fire interrupts manually via `fireInterrupt()` and verify
10
+ * that handlers were called with the correct arguments.
11
+ */
12
+ export class SimInterruptPin extends SimDigitalPin {
13
+ constructor(pinNum) {
14
+ super(pinNum, { interrupt: true });
15
+ this._handlers = new Map();
16
+ this._debounceMs = 0;
17
+ this._events = [];
18
+ }
19
+ // --- InterruptPin capability methods ---
20
+ onRising(handler, options) {
21
+ this._handlers.set('rising', handler);
22
+ if (options?.debounce)
23
+ this._debounceMs = options.debounce;
24
+ }
25
+ onFalling(handler, options) {
26
+ this._handlers.set('falling', handler);
27
+ if (options?.debounce)
28
+ this._debounceMs = options.debounce;
29
+ }
30
+ onChange(handler, options) {
31
+ this._handlers.set('change', handler);
32
+ if (options?.debounce)
33
+ this._debounceMs = options.debounce;
34
+ }
35
+ offInterrupts() {
36
+ this._handlers.clear();
37
+ }
38
+ /** Remove the rising-edge handler. */
39
+ offRising() {
40
+ this._handlers.delete('rising');
41
+ }
42
+ /** Remove the falling-edge handler. */
43
+ offFalling() {
44
+ this._handlers.delete('falling');
45
+ }
46
+ /** Remove all interrupt handlers. */
47
+ offAll() {
48
+ this._handlers.clear();
49
+ }
50
+ /** Check if any interrupt handlers are registered. */
51
+ hasInterrupt() {
52
+ return this._handlers.size > 0;
53
+ }
54
+ // --- Simulation helpers ---
55
+ /**
56
+ * Fire an interrupt manually from test code.
57
+ * @param mode - The interrupt mode to fire
58
+ * @param pinValue - The current pin value (for event logging)
59
+ */
60
+ fireInterrupt(mode, pinValue = 0) {
61
+ const handler = this._handlers.get(mode);
62
+ if (handler) {
63
+ handler();
64
+ }
65
+ // Also fire 'change' handler for any edge
66
+ if (mode !== 'change' && this._handlers.has('change')) {
67
+ this._handlers.get('change')();
68
+ }
69
+ this._events.push({
70
+ timestamp: Date.now() - this._startTime,
71
+ mode,
72
+ pinValue,
73
+ });
74
+ }
75
+ /**
76
+ * Simulate a pin value transition, automatically firing the appropriate interrupts.
77
+ * @param from - Previous pin value (0 or 1)
78
+ * @param to - New pin value (0 or 1)
79
+ */
80
+ simulateTransition(from, to) {
81
+ if (from === to)
82
+ return;
83
+ if (from === 0 && to === 1) {
84
+ this.fireInterrupt('rising', to);
85
+ }
86
+ else if (from === 1 && to === 0) {
87
+ this.fireInterrupt('falling', to);
88
+ }
89
+ }
90
+ /**
91
+ * Get all recorded interrupt events.
92
+ */
93
+ getEvents() {
94
+ return this._events;
95
+ }
96
+ /**
97
+ * Clear interrupt event history.
98
+ */
99
+ clearEvents() {
100
+ this._events = [];
101
+ }
102
+ /**
103
+ * Get the configured debounce time.
104
+ */
105
+ getDebounceMs() {
106
+ return this._debounceMs;
107
+ }
108
+ /**
109
+ * Reset to initial state.
110
+ */
111
+ reset() {
112
+ super.reset();
113
+ this._handlers.clear();
114
+ this._debounceMs = 0;
115
+ this._events = [];
116
+ this._startTime = Date.now();
117
+ }
118
+ }
@@ -0,0 +1,41 @@
1
+ import type { PWMPin } from '../contracts.js';
2
+ import type { AnalogValue, DigitalValue } from '@typecad/hal';
3
+ import { SimDigitalPin } from './digital-pin-sim.js';
4
+ /**
5
+ * Simulated PWM pin. Extends digital pin with PWM duty cycle control.
6
+ */
7
+ export declare class SimPWMPin extends SimDigitalPin implements PWMPin {
8
+ private _pwmPercent;
9
+ private _pwmFrequency;
10
+ private _pwmResolution;
11
+ private _attached;
12
+ constructor(pinNum: number);
13
+ write(value: DigitalValue | AnalogValue): void;
14
+ pwm(percent?: number): void;
15
+ setFrequency(hz: number): void;
16
+ /** Current PWM frequency in Hz (contract method name). */
17
+ getPwmFrequency(): number;
18
+ /** Current PWM resolution in bits (contract method name). */
19
+ getPwmResolution(): number;
20
+ /** @deprecated Use getPwmFrequency() to match the HAL contract. */
21
+ getFrequency(): number;
22
+ /** @deprecated Use getPwmResolution() to match the HAL contract. */
23
+ getResolution(): number;
24
+ /**
25
+ * Get the current PWM duty cycle as a percentage (0-100).
26
+ */
27
+ getPwmPercent(): number;
28
+ /**
29
+ * Get the current PWM duty cycle as a raw value (0 to 2^resolution - 1).
30
+ */
31
+ getPwmValue(): number;
32
+ /**
33
+ * Check if PWM is currently active.
34
+ */
35
+ isPwmActive(): boolean;
36
+ /**
37
+ * Set the PWM resolution in bits.
38
+ */
39
+ setResolution(bits: number): void;
40
+ reset(): void;
41
+ }
@@ -0,0 +1,85 @@
1
+ // ---------------------------------------------------------------------------
2
+ // @typecad/simulator — Simulated PWM pin
3
+ // ---------------------------------------------------------------------------
4
+ import { SimDigitalPin } from './digital-pin-sim.js';
5
+ /**
6
+ * Simulated PWM pin. Extends digital pin with PWM duty cycle control.
7
+ */
8
+ export class SimPWMPin extends SimDigitalPin {
9
+ constructor(pinNum) {
10
+ super(pinNum);
11
+ this._pwmPercent = 0;
12
+ this._pwmFrequency = 490; // Default Arduino PWM frequency
13
+ this._pwmResolution = 8; // Default 8-bit
14
+ this._attached = false;
15
+ }
16
+ // --- PWMPin ---
17
+ write(value) {
18
+ if (typeof value === 'number' && value > 1) {
19
+ // Analog write — treat as PWM duty cycle value
20
+ this.pwm((value / ((1 << this._pwmResolution) - 1)) * 100);
21
+ }
22
+ else {
23
+ super.write(value);
24
+ }
25
+ }
26
+ pwm(percent) {
27
+ // Calling pwm() (no args) activates PWM mode, pwm(x) sets duty cycle
28
+ // 0% duty cycle means PWM is inactive
29
+ this._attached = percent === undefined || percent > 0;
30
+ if (percent !== undefined) {
31
+ this._pwmPercent = Math.max(0, Math.min(100, percent));
32
+ }
33
+ }
34
+ setFrequency(hz) {
35
+ this._pwmFrequency = hz;
36
+ }
37
+ /** Current PWM frequency in Hz (contract method name). */
38
+ getPwmFrequency() {
39
+ return this._pwmFrequency;
40
+ }
41
+ /** Current PWM resolution in bits (contract method name). */
42
+ getPwmResolution() {
43
+ return this._pwmResolution;
44
+ }
45
+ /** @deprecated Use getPwmFrequency() to match the HAL contract. */
46
+ getFrequency() {
47
+ return this.getPwmFrequency();
48
+ }
49
+ /** @deprecated Use getPwmResolution() to match the HAL contract. */
50
+ getResolution() {
51
+ return this.getPwmResolution();
52
+ }
53
+ // --- Simulation helpers ---
54
+ /**
55
+ * Get the current PWM duty cycle as a percentage (0-100).
56
+ */
57
+ getPwmPercent() {
58
+ return this._pwmPercent;
59
+ }
60
+ /**
61
+ * Get the current PWM duty cycle as a raw value (0 to 2^resolution - 1).
62
+ */
63
+ getPwmValue() {
64
+ return Math.round((this._pwmPercent / 100) * ((1 << this._pwmResolution) - 1));
65
+ }
66
+ /**
67
+ * Check if PWM is currently active.
68
+ */
69
+ isPwmActive() {
70
+ return this._attached;
71
+ }
72
+ /**
73
+ * Set the PWM resolution in bits.
74
+ */
75
+ setResolution(bits) {
76
+ this._pwmResolution = bits;
77
+ }
78
+ reset() {
79
+ super.reset();
80
+ this._pwmPercent = 0;
81
+ this._pwmFrequency = 490;
82
+ this._pwmResolution = 8;
83
+ this._attached = false;
84
+ }
85
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Result of a byte read operation (used internally by bus simulators).
3
+ */
4
+ export interface IByteReadResult {
5
+ ok: boolean;
6
+ status: number;
7
+ bytes: Uint8Array;
8
+ bytesRead: number;
9
+ timedOut: boolean;
10
+ asUint8(): number;
11
+ asInt8(): number;
12
+ asUint16(endian: 'be' | 'le'): number;
13
+ asInt16(endian: 'be' | 'le'): number;
14
+ asUint32(endian: 'be' | 'le'): number;
15
+ asInt32(endian: 'be' | 'le'): number;
16
+ asString(): string;
17
+ asStringTrim(): string;
18
+ asInt(): number;
19
+ asFloat(): number;
20
+ unwrap(): Uint8Array;
21
+ unwrapOr(defaultValue: Uint8Array): Uint8Array;
22
+ }
23
+ /**
24
+ * Result of a write operation (used internally by bus simulators).
25
+ */
26
+ export interface IWriteResult {
27
+ ok: boolean;
28
+ status: number;
29
+ bytesWritten: number;
30
+ unwrap(): number;
31
+ unwrapOr(defaultValue: number): number;
32
+ }
33
+ /**
34
+ * Create an IByteReadResult with the given bytes.
35
+ */
36
+ export declare function createByteReadResult(bytes: Uint8Array, ok?: boolean, status?: number, timedOut?: boolean): IByteReadResult;
37
+ /**
38
+ * Create an IWriteResult with the given bytesWritten count.
39
+ */
40
+ export declare function createWriteResult(bytesWritten: number, ok?: boolean, status?: number): IWriteResult;
@@ -0,0 +1,57 @@
1
+ // ---------------------------------------------------------------------------
2
+ // @typecad/simulator — Result factory helpers
3
+ // ---------------------------------------------------------------------------
4
+ /**
5
+ * Create an IByteReadResult with the given bytes.
6
+ */
7
+ export function createByteReadResult(bytes, ok = true, status = 0, timedOut = false) {
8
+ return {
9
+ ok,
10
+ status,
11
+ bytes,
12
+ bytesRead: bytes.length,
13
+ timedOut,
14
+ asUint8() { return bytes[0] ?? 0; },
15
+ asInt8() { const v = bytes[0] ?? 0; return v > 127 ? v - 256 : v; },
16
+ asUint16(endian) {
17
+ if (bytes.length < 2)
18
+ return 0;
19
+ return endian === 'be'
20
+ ? ((bytes[0] << 8) | bytes[1]) >>> 0
21
+ : ((bytes[1] << 8) | bytes[0]) >>> 0;
22
+ },
23
+ asInt16(endian) {
24
+ const v = this.asUint16(endian);
25
+ return v > 32767 ? v - 65536 : v;
26
+ },
27
+ asUint32(endian) {
28
+ if (bytes.length < 4)
29
+ return 0;
30
+ return endian === 'be'
31
+ ? ((bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]) >>> 0
32
+ : ((bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | bytes[0]) >>> 0;
33
+ },
34
+ asInt32(endian) {
35
+ const v = this.asUint32(endian);
36
+ return v > 2147483647 ? v - 4294967296 : v;
37
+ },
38
+ asString() { return new TextDecoder().decode(bytes); },
39
+ asStringTrim() { return this.asString().trim(); },
40
+ asInt() { return parseInt(this.asString(), 10) || 0; },
41
+ asFloat() { return parseFloat(this.asString()) || 0; },
42
+ unwrap() { return bytes; },
43
+ unwrapOr(defaultValue) { return ok ? bytes : defaultValue; },
44
+ };
45
+ }
46
+ /**
47
+ * Create an IWriteResult with the given bytesWritten count.
48
+ */
49
+ export function createWriteResult(bytesWritten, ok = true, status = 0) {
50
+ return {
51
+ ok,
52
+ status,
53
+ bytesWritten,
54
+ unwrap() { return bytesWritten; },
55
+ unwrapOr(defaultValue) { return ok ? bytesWritten : defaultValue; },
56
+ };
57
+ }
@@ -0,0 +1,18 @@
1
+ export { SimDigitalPin } from './gpio/digital-pin-sim.js';
2
+ export { SimAnalogPin } from './gpio/analog-pin-sim.js';
3
+ export { SimPWMPin } from './gpio/pwm-pin-sim.js';
4
+ export { SimInterruptPin } from './gpio/interrupt-sim.js';
5
+ export type { InterruptEvent } from './gpio/interrupt-sim.js';
6
+ export { SimSerialPort } from './bus/serial-sim.js';
7
+ export { SimI2CBus } from './bus/i2c-sim.js';
8
+ export type { I2COperationLog } from './bus/i2c-sim.js';
9
+ export { SimSPIBus } from './bus/spi-sim.js';
10
+ export type { SPIOperationLog } from './bus/spi-sim.js';
11
+ export { SimBoard, createSimBoard } from './board/board-sim.js';
12
+ export { createBoardFromDefinition } from './board/from-definition.js';
13
+ export type { BasePin, PWMPin, AnalogPin, InterruptPin, IOutputModePin, IInputModePin, II2CBus, II2CDeviceAccessor, ISPIBus, ISPIDevice, IUARTBus, ISerialPort, PinCapabilityFlags, IToneAttachment, UARTStatusInfo, InterruptOptions, ErrorPolicy, } from './contracts.js';
14
+ export { I2CStatus, SPIStatus, UARTStatus } from './contracts.js';
15
+ export { hasPWM, hasAnalogInput, hasInterrupt, assertPWM, assertAnalog, assertInterrupt } from './contracts.js';
16
+ export { PinMode } from '@typecad/hal';
17
+ export type { PinChangeCallback, InterruptCallback, ISimI2CDevice, ISimSPIDevice, SimBoardType, SimBoardConfig, } from './types.js';
18
+ export { createByteReadResult, createWriteResult } from './helpers.js';
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ // ---------------------------------------------------------------------------
2
+ // @typecad/simulator — Barrel export
3
+ // ---------------------------------------------------------------------------
4
+ // --- GPIO simulation ---
5
+ export { SimDigitalPin } from './gpio/digital-pin-sim.js';
6
+ export { SimAnalogPin } from './gpio/analog-pin-sim.js';
7
+ export { SimPWMPin } from './gpio/pwm-pin-sim.js';
8
+ export { SimInterruptPin } from './gpio/interrupt-sim.js';
9
+ // --- Bus simulation ---
10
+ export { SimSerialPort } from './bus/serial-sim.js';
11
+ export { SimI2CBus } from './bus/i2c-sim.js';
12
+ export { SimSPIBus } from './bus/spi-sim.js';
13
+ // --- Board factory ---
14
+ export { SimBoard, createSimBoard } from './board/board-sim.js';
15
+ export { createBoardFromDefinition } from './board/from-definition.js';
16
+ export { I2CStatus, SPIStatus, UARTStatus } from './contracts.js';
17
+ export { hasPWM, hasAnalogInput, hasInterrupt, assertPWM, assertAnalog, assertInterrupt } from './contracts.js';
18
+ // --- Types ---
19
+ export { PinMode } from '@typecad/hal';
20
+ // --- Helpers ---
21
+ export { createByteReadResult, createWriteResult } from './helpers.js';