node-switchbot 4.0.0-beta.1 → 4.0.0-beta.10
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.
- package/.github/copilot-instructions.md +19 -5
- package/BLE.md +117 -4
- package/CHANGELOG.md +45 -0
- package/README.md +7 -1
- package/dist/api.d.ts +3 -3
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +9 -6
- package/dist/api.js.map +1 -1
- package/dist/ble.d.ts +38 -4
- package/dist/ble.d.ts.map +1 -1
- package/dist/ble.js +409 -53
- package/dist/ble.js.map +1 -1
- package/dist/devices/base.d.ts +83 -5
- package/dist/devices/base.d.ts.map +1 -1
- package/dist/devices/base.js +371 -34
- package/dist/devices/base.js.map +1 -1
- package/dist/devices/device-override-state-during-connection.d.ts +27 -0
- package/dist/devices/device-override-state-during-connection.d.ts.map +1 -0
- package/dist/devices/device-override-state-during-connection.js +45 -0
- package/dist/devices/device-override-state-during-connection.js.map +1 -0
- package/dist/devices/index.d.ts +4 -0
- package/dist/devices/index.d.ts.map +1 -1
- package/dist/devices/index.js +4 -0
- package/dist/devices/index.js.map +1 -1
- package/dist/devices/sequence-device.d.ts +36 -0
- package/dist/devices/sequence-device.d.ts.map +1 -0
- package/dist/devices/sequence-device.js +75 -0
- package/dist/devices/sequence-device.js.map +1 -0
- package/dist/devices/wo-air-purifier.d.ts +2 -2
- package/dist/devices/wo-air-purifier.d.ts.map +1 -1
- package/dist/devices/wo-air-purifier.js +2 -2
- package/dist/devices/wo-air-purifier.js.map +1 -1
- package/dist/devices/wo-bulb.d.ts +10 -0
- package/dist/devices/wo-bulb.d.ts.map +1 -1
- package/dist/devices/wo-bulb.js +69 -0
- package/dist/devices/wo-bulb.js.map +1 -1
- package/dist/devices/wo-curtain.d.ts +3 -3
- package/dist/devices/wo-curtain.d.ts.map +1 -1
- package/dist/devices/wo-curtain.js +12 -9
- package/dist/devices/wo-curtain.js.map +1 -1
- package/dist/devices/wo-hand.d.ts +53 -2
- package/dist/devices/wo-hand.d.ts.map +1 -1
- package/dist/devices/wo-hand.js +121 -3
- package/dist/devices/wo-hand.js.map +1 -1
- package/dist/devices/wo-lock-pro.d.ts +11 -2
- package/dist/devices/wo-lock-pro.d.ts.map +1 -1
- package/dist/devices/wo-lock-pro.js +65 -3
- package/dist/devices/wo-lock-pro.js.map +1 -1
- package/dist/devices/wo-lock.d.ts +7 -2
- package/dist/devices/wo-lock.d.ts.map +1 -1
- package/dist/devices/wo-lock.js +58 -3
- package/dist/devices/wo-lock.js.map +1 -1
- package/dist/devices/wo-plug-mini-us.d.ts +2 -2
- package/dist/devices/wo-plug-mini-us.d.ts.map +1 -1
- package/dist/devices/wo-plug-mini-us.js +2 -2
- package/dist/devices/wo-plug-mini-us.js.map +1 -1
- package/dist/devices/wo-relay-switch-1.d.ts +4 -2
- package/dist/devices/wo-relay-switch-1.d.ts.map +1 -1
- package/dist/devices/wo-relay-switch-1.js +36 -4
- package/dist/devices/wo-relay-switch-1.js.map +1 -1
- package/dist/devices/wo-relay-switch-2pm.d.ts +21 -0
- package/dist/devices/wo-relay-switch-2pm.d.ts.map +1 -0
- package/dist/devices/wo-relay-switch-2pm.js +39 -0
- package/dist/devices/wo-relay-switch-2pm.js.map +1 -0
- package/dist/devices/wo-rgbic-bulb.d.ts +29 -0
- package/dist/devices/wo-rgbic-bulb.d.ts.map +1 -0
- package/dist/devices/wo-rgbic-bulb.js +84 -0
- package/dist/devices/wo-rgbic-bulb.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/settings.d.ts +17 -0
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +18 -1
- package/dist/settings.js.map +1 -1
- package/dist/switchbot.d.ts.map +1 -1
- package/dist/switchbot.js +31 -8
- package/dist/switchbot.js.map +1 -1
- package/dist/types/ble.d.ts +20 -1
- package/dist/types/ble.d.ts.map +1 -1
- package/dist/types/ble.js.map +1 -1
- package/dist/types/device.d.ts +30 -3
- package/dist/types/device.d.ts.map +1 -1
- package/dist/types/index.d.ts +22 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/utils/bot-ble.d.ts +36 -0
- package/dist/utils/bot-ble.d.ts.map +1 -0
- package/dist/utils/bot-ble.js +109 -0
- package/dist/utils/bot-ble.js.map +1 -0
- package/dist/utils/circuit-breaker.d.ts +98 -0
- package/dist/utils/circuit-breaker.d.ts.map +1 -0
- package/dist/utils/circuit-breaker.js +187 -0
- package/dist/utils/circuit-breaker.js.map +1 -0
- package/dist/utils/connection-tracker.d.ts +66 -0
- package/dist/utils/connection-tracker.d.ts.map +1 -0
- package/dist/utils/connection-tracker.js +184 -0
- package/dist/utils/connection-tracker.js.map +1 -0
- package/dist/utils/fallback-handler.d.ts +68 -0
- package/dist/utils/fallback-handler.d.ts.map +1 -0
- package/dist/utils/fallback-handler.js +131 -0
- package/dist/utils/fallback-handler.js.map +1 -0
- package/dist/utils/index.d.ts +10 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +41 -4
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/retry.d.ts +55 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +95 -0
- package/dist/utils/retry.js.map +1 -0
- package/docs/assets/hierarchy.js +1 -1
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/APIError.html +2 -2
- package/docs/classes/APINotAvailableError.html +2 -2
- package/docs/classes/BLEConnection.html +16 -10
- package/docs/classes/BLENotAvailableError.html +2 -2
- package/docs/classes/BLEScanner.html +11 -9
- package/docs/classes/CommandFailedError.html +2 -2
- package/docs/classes/ConnectionTimeoutError.html +2 -2
- package/docs/classes/DeviceManager.html +13 -13
- package/docs/classes/DeviceNotFoundError.html +2 -2
- package/docs/classes/DeviceOverrideStateDuringConnection.html +56 -0
- package/docs/classes/DiscoveryError.html +2 -2
- package/docs/classes/OpenAPIClient.html +24 -24
- package/docs/classes/SequenceDevice.html +58 -0
- package/docs/classes/SwitchBot.html +11 -11
- package/docs/classes/SwitchBotDevice.html +43 -15
- package/docs/classes/SwitchBotError.html +2 -2
- package/docs/classes/ValidationError.html +2 -2
- package/docs/classes/WoAirPurifier.html +48 -18
- package/docs/classes/WoAirPurifierTable.html +48 -18
- package/docs/classes/WoBlindTilt.html +48 -20
- package/docs/classes/WoBulb.html +52 -19
- package/docs/classes/WoCeilingLight.html +52 -19
- package/docs/classes/WoContact.html +42 -14
- package/docs/classes/WoCurtain.html +46 -18
- package/docs/classes/WoHand.html +63 -19
- package/docs/classes/WoHub2.html +42 -14
- package/docs/classes/WoHub3.html +42 -14
- package/docs/classes/WoHumi.html +46 -18
- package/docs/classes/WoHumi2.html +46 -18
- package/docs/classes/WoIOSensorTH.html +42 -14
- package/docs/classes/WoKeypad.html +42 -14
- package/docs/classes/WoLeak.html +42 -14
- package/docs/classes/WoPlugMiniJP.html +45 -17
- package/docs/classes/WoPlugMiniUS.html +45 -17
- package/docs/classes/WoPresence.html +42 -14
- package/docs/classes/WoRelaySwitch1.html +47 -17
- package/docs/classes/WoRelaySwitch1PM.html +47 -17
- package/docs/classes/WoRemote.html +42 -14
- package/docs/classes/WoSensorTH.html +42 -14
- package/docs/classes/WoSensorTHPlus.html +42 -14
- package/docs/classes/WoSensorTHPro.html +42 -14
- package/docs/classes/WoSensorTHProCO2.html +42 -14
- package/docs/classes/WoSmartLock.html +49 -16
- package/docs/classes/WoSmartLockPro.html +52 -17
- package/docs/classes/WoStrip.html +52 -19
- package/docs/enums/LogLevel.html +2 -2
- package/docs/enums/SwitchBotBLEModel.html +2 -2
- package/docs/enums/SwitchBotBLEModelName.html +2 -2
- package/docs/functions/updateBaseURL.html +1 -1
- package/docs/hierarchy.html +1 -1
- package/docs/index.html +2 -2
- package/docs/interfaces/APICommandRequest.html +2 -2
- package/docs/interfaces/APICommandResponse.html +2 -2
- package/docs/interfaces/APIDevice.html +2 -2
- package/docs/interfaces/APIDeviceStatus.html +2 -2
- package/docs/interfaces/APIErrorResponse.html +2 -2
- package/docs/interfaces/APIResponse.html +2 -2
- package/docs/interfaces/AirPurifierCommands.html +2 -2
- package/docs/interfaces/AirPurifierServiceData.html +20 -5
- package/docs/interfaces/AirPurifierStatus.html +7 -7
- package/docs/interfaces/BLEAdvertisement.html +3 -2
- package/docs/interfaces/BLEScanOptions.html +5 -5
- package/docs/interfaces/BLEServiceData.html +22 -5
- package/docs/interfaces/BlindTiltCommands.html +2 -2
- package/docs/interfaces/BlindTiltServiceData.html +21 -5
- package/docs/interfaces/BlindTiltStatus.html +6 -6
- package/docs/interfaces/BotCommands.html +6 -2
- package/docs/interfaces/BotServiceData.html +20 -5
- package/docs/interfaces/BotStatus.html +6 -6
- package/docs/interfaces/BulbCommands.html +4 -2
- package/docs/interfaces/BulbServiceData.html +21 -5
- package/docs/interfaces/BulbStatus.html +6 -6
- package/docs/interfaces/CeilingLightCommands.html +4 -2
- package/docs/interfaces/CeilingLightServiceData.html +21 -5
- package/docs/interfaces/CeilingLightStatus.html +6 -6
- package/docs/interfaces/CommandResult.html +6 -6
- package/docs/interfaces/ContactServiceData.html +22 -5
- package/docs/interfaces/ContactStatus.html +6 -6
- package/docs/interfaces/CurtainCommands.html +2 -2
- package/docs/interfaces/CurtainServiceData.html +22 -5
- package/docs/interfaces/CurtainStatus.html +6 -6
- package/docs/interfaces/DeviceInfo.html +23 -13
- package/docs/interfaces/DeviceListResponse.html +2 -2
- package/docs/interfaces/DeviceStatus.html +6 -6
- package/docs/interfaces/DiscoveryOptions.html +7 -7
- package/docs/interfaces/HubServiceData.html +22 -5
- package/docs/interfaces/HubStatus.html +6 -6
- package/docs/interfaces/HumidifierCommands.html +2 -2
- package/docs/interfaces/HumidifierServiceData.html +23 -6
- package/docs/interfaces/HumidifierStatus.html +6 -6
- package/docs/interfaces/KeypadStatus.html +6 -6
- package/docs/interfaces/LeakServiceData.html +22 -5
- package/docs/interfaces/LeakStatus.html +6 -6
- package/docs/interfaces/LockCommands.html +6 -2
- package/docs/interfaces/LockServiceData.html +20 -6
- package/docs/interfaces/LockStatus.html +6 -6
- package/docs/interfaces/MeterServiceData.html +22 -5
- package/docs/interfaces/MeterStatus.html +6 -6
- package/docs/interfaces/MotionServiceData.html +22 -5
- package/docs/interfaces/MotionStatus.html +6 -6
- package/docs/interfaces/PlugCommands.html +2 -2
- package/docs/interfaces/PlugServiceData.html +21 -5
- package/docs/interfaces/PlugStatus.html +6 -6
- package/docs/interfaces/PresenceServiceData.html +22 -5
- package/docs/interfaces/PresenceStatus.html +6 -6
- package/docs/interfaces/RelaySwitchCommands.html +2 -2
- package/docs/interfaces/RelaySwitchServiceData.html +21 -5
- package/docs/interfaces/RelaySwitchStatus.html +6 -6
- package/docs/interfaces/RemoteStatus.html +6 -6
- package/docs/interfaces/SceneListResponse.html +2 -2
- package/docs/interfaces/StripCommands.html +4 -2
- package/docs/interfaces/StripServiceData.html +21 -5
- package/docs/interfaces/StripStatus.html +6 -6
- package/docs/interfaces/SwitchBotConfig.html +21 -9
- package/docs/interfaces/WebhookConfig.html +2 -2
- package/docs/interfaces/WebhookDetails.html +2 -2
- package/docs/interfaces/WebhookQueryResponse.html +2 -2
- package/docs/interfaces/WebhookSetupResponse.html +2 -2
- package/docs/media/BLE.md +117 -4
- package/docs/modules.html +1 -1
- package/docs/types/ConnectionType.html +1 -1
- package/docs/types/PhysicalDeviceType.html +1 -1
- package/docs/types/VirtualDeviceType.html +1 -1
- package/docs/variables/urls.html +1 -1
- package/package.json +11 -7
- package/tmp-switchbot-scan.mjs +79 -0
- package/todo/PYSWITCHBOT_COMPARISON.md +484 -0
- package/todo/README.md +68 -0
- package/todo/completed.md +134 -0
- package/todo/todo.md +296 -0
- package/tsconfig.build.json +17 -0
- package/PRODUCTION_READY.md +0 -135
package/dist/types/device.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Buffer } from 'node:buffer';
|
|
1
2
|
import type { DeviceStatus } from './index.js';
|
|
2
3
|
export type { DeviceStatus };
|
|
3
4
|
/**
|
|
@@ -11,6 +12,10 @@ export interface BotCommands {
|
|
|
11
12
|
turnOn: () => Promise<boolean>;
|
|
12
13
|
turnOff: () => Promise<boolean>;
|
|
13
14
|
press: () => Promise<boolean>;
|
|
15
|
+
setMode?: (mode: 'press' | 'switch') => Promise<boolean>;
|
|
16
|
+
setLongPress?: (duration: number) => Promise<boolean>;
|
|
17
|
+
handUp?: () => Promise<boolean>;
|
|
18
|
+
handDown?: () => Promise<boolean>;
|
|
14
19
|
}
|
|
15
20
|
/**
|
|
16
21
|
* Curtain (WoCurtain) specific types
|
|
@@ -23,10 +28,10 @@ export interface CurtainStatus extends DeviceStatus {
|
|
|
23
28
|
slidePosition?: number;
|
|
24
29
|
}
|
|
25
30
|
export interface CurtainCommands {
|
|
26
|
-
open: () => Promise<boolean>;
|
|
27
|
-
close: () => Promise<boolean>;
|
|
31
|
+
open: (speed?: number) => Promise<boolean>;
|
|
32
|
+
close: (speed?: number) => Promise<boolean>;
|
|
28
33
|
pause: () => Promise<boolean>;
|
|
29
|
-
setPosition: (position: number) => Promise<boolean>;
|
|
34
|
+
setPosition: (position: number, speed?: number) => Promise<boolean>;
|
|
30
35
|
}
|
|
31
36
|
/**
|
|
32
37
|
* Lock (WoSmartLock) specific types
|
|
@@ -39,6 +44,10 @@ export interface LockStatus extends DeviceStatus {
|
|
|
39
44
|
export interface LockCommands {
|
|
40
45
|
lock: () => Promise<boolean>;
|
|
41
46
|
unlock: () => Promise<boolean>;
|
|
47
|
+
unlockWithoutUnlatch?: () => Promise<boolean>;
|
|
48
|
+
getLockInfo?: () => Promise<Record<string, unknown>>;
|
|
49
|
+
onLockNotification?: (handler: (payload: Buffer) => void) => Promise<void>;
|
|
50
|
+
offLockNotification?: (handler: (payload: Buffer) => void) => void;
|
|
42
51
|
}
|
|
43
52
|
/**
|
|
44
53
|
* Meter (Temperature/Humidity) specific types
|
|
@@ -96,6 +105,17 @@ export interface BulbCommands {
|
|
|
96
105
|
setBrightness: (brightness: number) => Promise<boolean>;
|
|
97
106
|
setColorTemperature: (temperature: number) => Promise<boolean>;
|
|
98
107
|
setColor: (red: number, green: number, blue: number) => Promise<boolean>;
|
|
108
|
+
setEffect?: (effectName: string, speed?: number) => Promise<boolean>;
|
|
109
|
+
setColorTemp?: (minTemp: number, maxTemp: number, temp: number) => Promise<boolean>;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* RGBIC Bulb specific types (segmented/multi-zone color control)
|
|
113
|
+
*/
|
|
114
|
+
export interface RGBICBulbStatus extends BulbStatus {
|
|
115
|
+
}
|
|
116
|
+
export interface RGBICBulbCommands extends BulbCommands {
|
|
117
|
+
setSegmentColor?: (segmentId: number, red: number, green: number, blue: number) => Promise<boolean>;
|
|
118
|
+
setSegmentEffect?: (segmentId: number, effectName: string, speed?: number) => Promise<boolean>;
|
|
99
119
|
}
|
|
100
120
|
/**
|
|
101
121
|
* Strip Light specific types
|
|
@@ -195,6 +215,13 @@ export interface RelaySwitchCommands {
|
|
|
195
215
|
turnOff: () => Promise<boolean>;
|
|
196
216
|
toggle: () => Promise<boolean>;
|
|
197
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* Relay Switch 2PM specific types (with channel-specific control)
|
|
220
|
+
*/
|
|
221
|
+
export interface RelaySwitchChannelCommands extends RelaySwitchCommands {
|
|
222
|
+
setChannel1?: (state: boolean) => Promise<boolean>;
|
|
223
|
+
setChannel2?: (state: boolean) => Promise<boolean>;
|
|
224
|
+
}
|
|
198
225
|
/**
|
|
199
226
|
* Keypad specific types
|
|
200
227
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../src/types/device.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C,YAAY,EAAE,YAAY,EAAE,CAAA;AAE5B;;GAEG;AACH,MAAM,WAAW,SAAU,SAAQ,YAAY;IAC7C,KAAK,EAAE,IAAI,GAAG,KAAK,CAAA;IACnB,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,WAAW,CAAA;CACxC;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;IAC9B,OAAO,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;IAC/B,KAAK,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../src/types/device.ts"],"names":[],"mappings":"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"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -32,6 +32,18 @@ export interface SwitchBotConfig {
|
|
|
32
32
|
logLevel?: LogLevel;
|
|
33
33
|
/** Noble instance (optional - for custom BLE configuration) */
|
|
34
34
|
noble?: any;
|
|
35
|
+
/** Enable intelligent connection selection based on success history (default: true) */
|
|
36
|
+
enableConnectionIntelligence?: boolean;
|
|
37
|
+
/** Enable circuit breaker for connection reliability (default: true) */
|
|
38
|
+
enableCircuitBreaker?: boolean;
|
|
39
|
+
/** Enable automatic retry with exponential backoff (default: true) */
|
|
40
|
+
enableRetry?: boolean;
|
|
41
|
+
/** Maximum retry attempts per command (default: 3) */
|
|
42
|
+
maxRetryAttempts?: number;
|
|
43
|
+
/** Initial retry delay in milliseconds (default: 100) */
|
|
44
|
+
retryInitialDelayMs?: number;
|
|
45
|
+
/** Maximum retry delay in milliseconds (default: 5000) */
|
|
46
|
+
retryMaxDelayMs?: number;
|
|
35
47
|
}
|
|
36
48
|
/**
|
|
37
49
|
* Device discovery options
|
|
@@ -64,6 +76,8 @@ export interface DeviceInfo {
|
|
|
64
76
|
model?: string;
|
|
65
77
|
/** MAC address (for BLE devices) */
|
|
66
78
|
mac?: string;
|
|
79
|
+
/** BLE peripheral/advertisement ID (for ID-based lookups on macOS) */
|
|
80
|
+
bleId?: string;
|
|
67
81
|
/** Available connection types */
|
|
68
82
|
connectionTypes: ConnectionType[];
|
|
69
83
|
/** Current active connection type */
|
|
@@ -74,6 +88,14 @@ export interface DeviceInfo {
|
|
|
74
88
|
battery?: number;
|
|
75
89
|
/** RSSI signal strength (for BLE) */
|
|
76
90
|
rssi?: number;
|
|
91
|
+
/** Last parsed BLE advertisement service data */
|
|
92
|
+
bleServiceData?: Record<string, unknown>;
|
|
93
|
+
/** Optional BLE encryption key as hex (16 bytes / 32 hex chars) */
|
|
94
|
+
encryptionKey?: string;
|
|
95
|
+
/** Optional BLE encryption IV as hex */
|
|
96
|
+
encryptionIV?: string;
|
|
97
|
+
/** Optional BLE encryption mode */
|
|
98
|
+
encryptionMode?: 'auto' | 'ctr' | 'gcm';
|
|
77
99
|
/** Firmware version */
|
|
78
100
|
version?: string;
|
|
79
101
|
/** CloudService enabled in OpenAPI */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,oBAAY,QAAQ;IAClB,IAAI,IAAI;IACR,KAAK,IAAI;IACT,IAAI,IAAI;IACR,IAAI,IAAI;IACR,KAAK,IAAI;CACV;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ,CAAA;AAErD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,mDAAmD;IACnD,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,2DAA2D;IAC3D,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,+DAA+D;IAC/D,KAAK,CAAC,EAAE,GAAG,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
|
package/dist/types/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,CAAN,IAAY,QAMX;AAND,WAAY,QAAQ;IAClB,uCAAQ,CAAA;IACR,yCAAS,CAAA;IACT,uCAAQ,CAAA;IACR,uCAAQ,CAAA;IACR,yCAAS,CAAA;AACX,CAAC,EANW,QAAQ,KAAR,QAAQ,QAMnB;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,CAAN,IAAY,QAMX;AAND,WAAY,QAAQ;IAClB,uCAAQ,CAAA;IACR,yCAAS,CAAA;IACT,uCAAQ,CAAA;IACR,uCAAQ,CAAA;IACR,yCAAS,CAAA;AACX,CAAC,EANW,QAAQ,KAAR,QAAQ,QAMnB;AAmID,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,aAAa,CAAA"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Buffer } from 'node:buffer';
|
|
2
|
+
/**
|
|
3
|
+
* Bot BLE action types
|
|
4
|
+
*/
|
|
5
|
+
export type BotBleAction = 0x00 | 0x01 | 0x02;
|
|
6
|
+
/**
|
|
7
|
+
* Valid Bot BLE action values
|
|
8
|
+
*/
|
|
9
|
+
export declare const BOT_BLE_ACTIONS: {
|
|
10
|
+
PRESS: BotBleAction;
|
|
11
|
+
TURN_ON: BotBleAction;
|
|
12
|
+
TURN_OFF: BotBleAction;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Validate Bot BLE password format
|
|
16
|
+
* Password must be exactly 4 alphanumeric characters (case-sensitive)
|
|
17
|
+
* @param password - Password to validate
|
|
18
|
+
* @throws Error if password format is invalid
|
|
19
|
+
*/
|
|
20
|
+
export declare function validateBotPassword(password: string): void;
|
|
21
|
+
/**
|
|
22
|
+
* Build Bot BLE command buffer
|
|
23
|
+
* @param action - Bot action (0x00=press, 0x01=on, 0x02=off)
|
|
24
|
+
* @param password - Optional 4-character password for encrypted commands
|
|
25
|
+
* @returns Command buffer ready to send via BLE
|
|
26
|
+
* @throws Error if action or password format is invalid
|
|
27
|
+
*/
|
|
28
|
+
export declare function buildBotBleCommand(action: BotBleAction, password?: string): Buffer;
|
|
29
|
+
/**
|
|
30
|
+
* Parse Bot BLE response buffer
|
|
31
|
+
* @param response - Response buffer from Bot device
|
|
32
|
+
* @returns True if command was successful
|
|
33
|
+
* @throws Error if response indicates failure
|
|
34
|
+
*/
|
|
35
|
+
export declare function parseBotBleResponse(response: Buffer): boolean;
|
|
36
|
+
//# sourceMappingURL=bot-ble.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bot-ble.d.ts","sourceRoot":"","sources":["../../src/utils/bot-ble.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAmCpC;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AAE7C;;GAEG;AACH,eAAO,MAAM,eAAe;WACX,YAAY;aACV,YAAY;cACX,YAAY;CAC/B,CAAA;AAKD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAM1D;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,YAAY,EACpB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAgCR;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAc7D"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved.
|
|
2
|
+
*
|
|
3
|
+
* utils/bot-ble.ts: SwitchBot v4.0.0 - Bot BLE Password Helpers
|
|
4
|
+
*/
|
|
5
|
+
import { Buffer } from 'node:buffer';
|
|
6
|
+
/**
|
|
7
|
+
* CRC32 polynomial for password encryption
|
|
8
|
+
*/
|
|
9
|
+
const CRC32_POLYNOMIAL = 0xEDB88320;
|
|
10
|
+
/**
|
|
11
|
+
* Precomputed CRC32 lookup table
|
|
12
|
+
*/
|
|
13
|
+
const CRC32_TABLE = new Uint32Array(256);
|
|
14
|
+
// Initialize CRC32 table
|
|
15
|
+
for (let i = 0; i < 256; i++) {
|
|
16
|
+
let crc = i;
|
|
17
|
+
for (let j = 0; j < 8; j++) {
|
|
18
|
+
crc = (crc & 1) !== 0 ? (crc >>> 1) ^ CRC32_POLYNOMIAL : (crc >>> 1);
|
|
19
|
+
}
|
|
20
|
+
CRC32_TABLE[i] = crc >>> 0;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Calculate CRC32 checksum of a string
|
|
24
|
+
* @param input - String to calculate CRC32 for
|
|
25
|
+
* @returns CRC32 checksum as unsigned 32-bit integer
|
|
26
|
+
*/
|
|
27
|
+
function calculateCRC32(input) {
|
|
28
|
+
let crc = 0xFFFFFFFF;
|
|
29
|
+
for (let i = 0; i < input.length; i++) {
|
|
30
|
+
const byte = input.charCodeAt(i);
|
|
31
|
+
crc = (crc >>> 8) ^ CRC32_TABLE[(crc ^ byte) & 0xFF];
|
|
32
|
+
}
|
|
33
|
+
return (crc ^ 0xFFFFFFFF) >>> 0;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Valid Bot BLE action values
|
|
37
|
+
*/
|
|
38
|
+
export const BOT_BLE_ACTIONS = {
|
|
39
|
+
PRESS: 0x00,
|
|
40
|
+
TURN_ON: 0x01,
|
|
41
|
+
TURN_OFF: 0x02,
|
|
42
|
+
};
|
|
43
|
+
// Regex pattern at module scope to avoid recompilation
|
|
44
|
+
const PASSWORD_REGEX = /^[A-Z0-9]{4}$/i;
|
|
45
|
+
/**
|
|
46
|
+
* Validate Bot BLE password format
|
|
47
|
+
* Password must be exactly 4 alphanumeric characters (case-sensitive)
|
|
48
|
+
* @param password - Password to validate
|
|
49
|
+
* @throws Error if password format is invalid
|
|
50
|
+
*/
|
|
51
|
+
export function validateBotPassword(password) {
|
|
52
|
+
if (!PASSWORD_REGEX.test(password)) {
|
|
53
|
+
throw new Error('Invalid Bot password. Password must be exactly 4 alphanumeric characters (case-sensitive).');
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Build Bot BLE command buffer
|
|
58
|
+
* @param action - Bot action (0x00=press, 0x01=on, 0x02=off)
|
|
59
|
+
* @param password - Optional 4-character password for encrypted commands
|
|
60
|
+
* @returns Command buffer ready to send via BLE
|
|
61
|
+
* @throws Error if action or password format is invalid
|
|
62
|
+
*/
|
|
63
|
+
export function buildBotBleCommand(action, password) {
|
|
64
|
+
// Validate action
|
|
65
|
+
const validActions = [
|
|
66
|
+
BOT_BLE_ACTIONS.PRESS,
|
|
67
|
+
BOT_BLE_ACTIONS.TURN_ON,
|
|
68
|
+
BOT_BLE_ACTIONS.TURN_OFF,
|
|
69
|
+
];
|
|
70
|
+
if (!validActions.includes(action)) {
|
|
71
|
+
throw new Error(`Invalid Bot BLE action: 0x${action.toString(16)}. Expected 0x00, 0x01, or 0x02.`);
|
|
72
|
+
}
|
|
73
|
+
// Plain command (no password)
|
|
74
|
+
if (!password) {
|
|
75
|
+
return Buffer.from([0x57, 0x01, action]);
|
|
76
|
+
}
|
|
77
|
+
// Encrypted command (with password)
|
|
78
|
+
validateBotPassword(password);
|
|
79
|
+
const crc = calculateCRC32(password);
|
|
80
|
+
// Command format: [0x57, 0x11, CRC32_BE (4 bytes), action]
|
|
81
|
+
return Buffer.from([
|
|
82
|
+
0x57,
|
|
83
|
+
0x11,
|
|
84
|
+
(crc >>> 24) & 0xFF, // MSB first (big-endian)
|
|
85
|
+
(crc >>> 16) & 0xFF,
|
|
86
|
+
(crc >>> 8) & 0xFF,
|
|
87
|
+
crc & 0xFF, // LSB
|
|
88
|
+
action,
|
|
89
|
+
]);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Parse Bot BLE response buffer
|
|
93
|
+
* @param response - Response buffer from Bot device
|
|
94
|
+
* @returns True if command was successful
|
|
95
|
+
* @throws Error if response indicates failure
|
|
96
|
+
*/
|
|
97
|
+
export function parseBotBleResponse(response) {
|
|
98
|
+
if (response.length !== 3) {
|
|
99
|
+
throw new Error(`Invalid Bot response length: ${response.length}, expected 3`);
|
|
100
|
+
}
|
|
101
|
+
const statusCode = response.readUInt8(0);
|
|
102
|
+
// Success codes: 0x01 (success) or 0x05 (success, encrypted)
|
|
103
|
+
if (statusCode === 0x01 || statusCode === 0x05) {
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
// Error response
|
|
107
|
+
throw new Error(`Bot command failed with status: 0x${response.toString('hex')}`);
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=bot-ble.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bot-ble.js","sourceRoot":"","sources":["../../src/utils/bot-ble.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Circuit breaker states
|
|
3
|
+
*/
|
|
4
|
+
export declare enum CircuitBreakerState {
|
|
5
|
+
CLOSED = "CLOSED",// Normal operation
|
|
6
|
+
OPEN = "OPEN",// Failing, reject requests
|
|
7
|
+
HALF_OPEN = "HALF_OPEN"
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Circuit breaker configuration
|
|
11
|
+
*/
|
|
12
|
+
export interface CircuitBreakerConfig {
|
|
13
|
+
/** Failure threshold (0-1) to open circuit (default: 0.5) */
|
|
14
|
+
failureThreshold?: number;
|
|
15
|
+
/** Minimum number of requests before checking threshold (default: 5) */
|
|
16
|
+
minRequests?: number;
|
|
17
|
+
/** Time to wait before attempting recovery in milliseconds (default: 30000) */
|
|
18
|
+
resetTimeoutMs?: number;
|
|
19
|
+
/** Maximum number of requests in half-open state (default: 1) */
|
|
20
|
+
maxHalfOpenRequests?: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Circuit breaker statistics
|
|
24
|
+
*/
|
|
25
|
+
export interface CircuitBreakerStats {
|
|
26
|
+
state: CircuitBreakerState;
|
|
27
|
+
successCount: number;
|
|
28
|
+
failureCount: number;
|
|
29
|
+
successRate: number;
|
|
30
|
+
totalRequests: number;
|
|
31
|
+
lastFailureTime?: Date;
|
|
32
|
+
lastRecoveryTime?: Date;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Circuit breaker for managing connection reliability
|
|
36
|
+
*/
|
|
37
|
+
export declare class CircuitBreaker {
|
|
38
|
+
private name;
|
|
39
|
+
private state;
|
|
40
|
+
private successCount;
|
|
41
|
+
private failureCount;
|
|
42
|
+
private halfOpenAttempts;
|
|
43
|
+
private lastFailureTime?;
|
|
44
|
+
private lastRecoveryTime?;
|
|
45
|
+
private resetTimer?;
|
|
46
|
+
private logger;
|
|
47
|
+
private config;
|
|
48
|
+
constructor(name: string, config?: CircuitBreakerConfig, logLevel?: number);
|
|
49
|
+
/**
|
|
50
|
+
* Record a successful operation
|
|
51
|
+
*/
|
|
52
|
+
recordSuccess(): void;
|
|
53
|
+
/**
|
|
54
|
+
* Record a failed operation
|
|
55
|
+
*/
|
|
56
|
+
recordFailure(): void;
|
|
57
|
+
/**
|
|
58
|
+
* Check if circuit should open based on failure rate
|
|
59
|
+
*/
|
|
60
|
+
private shouldOpen;
|
|
61
|
+
/**
|
|
62
|
+
* Transition to CLOSED state (recovered)
|
|
63
|
+
*/
|
|
64
|
+
private transitionToClosed;
|
|
65
|
+
/**
|
|
66
|
+
* Transition to OPEN state (failing)
|
|
67
|
+
*/
|
|
68
|
+
private transitionToOpen;
|
|
69
|
+
/**
|
|
70
|
+
* Check if the circuit allows operations
|
|
71
|
+
*/
|
|
72
|
+
canExecute(): boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Mark that we tried to execute in half-open state
|
|
75
|
+
*/
|
|
76
|
+
markHalfOpenAttempt(): void;
|
|
77
|
+
/**
|
|
78
|
+
* Get current state
|
|
79
|
+
*/
|
|
80
|
+
getState(): CircuitBreakerState;
|
|
81
|
+
/**
|
|
82
|
+
* Get current failure rate (0-1)
|
|
83
|
+
*/
|
|
84
|
+
getFailureRate(): number;
|
|
85
|
+
/**
|
|
86
|
+
* Get statistics
|
|
87
|
+
*/
|
|
88
|
+
getStats(): CircuitBreakerStats;
|
|
89
|
+
/**
|
|
90
|
+
* Reset circuit breaker (for testing)
|
|
91
|
+
*/
|
|
92
|
+
reset(): void;
|
|
93
|
+
/**
|
|
94
|
+
* Cleanup
|
|
95
|
+
*/
|
|
96
|
+
cleanup(): void;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=circuit-breaker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circuit-breaker.d.ts","sourceRoot":"","sources":["../../src/utils/circuit-breaker.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,oBAAY,mBAAmB;IAC7B,MAAM,WAAW,CAAE,mBAAmB;IACtC,IAAI,SAAS,CAAE,2BAA2B;IAC1C,SAAS,cAAc;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,+EAA+E;IAC/E,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,iEAAiE;IACjE,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,mBAAmB,CAAA;IAC1B,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,CAAC,EAAE,IAAI,CAAA;IACtB,gBAAgB,CAAC,EAAE,IAAI,CAAA;CACxB;AAED;;GAEG;AACH,qBAAa,cAAc;IAYvB,OAAO,CAAC,IAAI;IAXd,OAAO,CAAC,KAAK,CAAkD;IAC/D,OAAO,CAAC,YAAY,CAAI;IACxB,OAAO,CAAC,YAAY,CAAI;IACxB,OAAO,CAAC,gBAAgB,CAAI;IAC5B,OAAO,CAAC,eAAe,CAAC,CAAM;IAC9B,OAAO,CAAC,gBAAgB,CAAC,CAAM;IAC/B,OAAO,CAAC,UAAU,CAAC,CAAgB;IACnC,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,MAAM,CAAgC;gBAGpC,IAAI,EAAE,MAAM,EACpB,MAAM,GAAE,oBAAyB,EACjC,QAAQ,CAAC,EAAE,MAAM;IAYnB;;OAEG;IACH,aAAa,IAAI,IAAI;IAUrB;;OAEG;IACH,aAAa,IAAI,IAAI;IAmBrB;;OAEG;IACH,OAAO,CAAC,UAAU;IAWlB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAa1B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAkBxB;;OAEG;IACH,UAAU,IAAI,OAAO;IAarB;;OAEG;IACH,mBAAmB,IAAI,IAAI;IAM3B;;OAEG;IACH,QAAQ,IAAI,mBAAmB;IAI/B;;OAEG;IACH,cAAc,IAAI,MAAM;IAKxB;;OAEG;IACH,QAAQ,IAAI,mBAAmB;IAc/B;;OAEG;IACH,KAAK,IAAI,IAAI;IAeb;;OAEG;IACH,OAAO,IAAI,IAAI;CAMhB"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved.
|
|
2
|
+
*
|
|
3
|
+
* utils/circuit-breaker.ts: SwitchBot v4.0.0 - Circuit Breaker Pattern
|
|
4
|
+
*/
|
|
5
|
+
import { Logger } from './index.js';
|
|
6
|
+
/**
|
|
7
|
+
* Circuit breaker states
|
|
8
|
+
*/
|
|
9
|
+
export var CircuitBreakerState;
|
|
10
|
+
(function (CircuitBreakerState) {
|
|
11
|
+
CircuitBreakerState["CLOSED"] = "CLOSED";
|
|
12
|
+
CircuitBreakerState["OPEN"] = "OPEN";
|
|
13
|
+
CircuitBreakerState["HALF_OPEN"] = "HALF_OPEN";
|
|
14
|
+
})(CircuitBreakerState || (CircuitBreakerState = {}));
|
|
15
|
+
/**
|
|
16
|
+
* Circuit breaker for managing connection reliability
|
|
17
|
+
*/
|
|
18
|
+
export class CircuitBreaker {
|
|
19
|
+
name;
|
|
20
|
+
state = CircuitBreakerState.CLOSED;
|
|
21
|
+
successCount = 0;
|
|
22
|
+
failureCount = 0;
|
|
23
|
+
halfOpenAttempts = 0;
|
|
24
|
+
lastFailureTime;
|
|
25
|
+
lastRecoveryTime;
|
|
26
|
+
resetTimer;
|
|
27
|
+
logger;
|
|
28
|
+
config;
|
|
29
|
+
constructor(name, config = {}, logLevel) {
|
|
30
|
+
this.name = name;
|
|
31
|
+
this.config = {
|
|
32
|
+
failureThreshold: config.failureThreshold ?? 0.5,
|
|
33
|
+
minRequests: config.minRequests ?? 5,
|
|
34
|
+
resetTimeoutMs: config.resetTimeoutMs ?? 30000,
|
|
35
|
+
maxHalfOpenRequests: config.maxHalfOpenRequests ?? 1,
|
|
36
|
+
};
|
|
37
|
+
this.logger = new Logger(`CircuitBreaker:${name}`, logLevel);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Record a successful operation
|
|
41
|
+
*/
|
|
42
|
+
recordSuccess() {
|
|
43
|
+
this.successCount++;
|
|
44
|
+
if (this.state === CircuitBreakerState.HALF_OPEN) {
|
|
45
|
+
// Successful in Half-Open -> recover
|
|
46
|
+
this.logger.info(`${this.name}: circuit recovered (HALF_OPEN -> CLOSED)`);
|
|
47
|
+
this.transitionToClosed();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Record a failed operation
|
|
52
|
+
*/
|
|
53
|
+
recordFailure() {
|
|
54
|
+
this.failureCount++;
|
|
55
|
+
this.lastFailureTime = new Date();
|
|
56
|
+
if (this.state === CircuitBreakerState.CLOSED) {
|
|
57
|
+
// Check if we should open the circuit
|
|
58
|
+
if (this.shouldOpen()) {
|
|
59
|
+
this.logger.warn(`${this.name}: circuit opened - failure rate ${this.getFailureRate().toFixed(2)}`);
|
|
60
|
+
this.transitionToOpen();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else if (this.state === CircuitBreakerState.HALF_OPEN) {
|
|
64
|
+
// Failed during recovery -> reopen
|
|
65
|
+
this.logger.warn(`${this.name}: circuit reopened (HALF_OPEN -> OPEN)`);
|
|
66
|
+
this.transitionToOpen();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Check if circuit should open based on failure rate
|
|
71
|
+
*/
|
|
72
|
+
shouldOpen() {
|
|
73
|
+
const totalRequests = this.successCount + this.failureCount;
|
|
74
|
+
if (totalRequests < this.config.minRequests) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
const failureRate = this.failureCount / totalRequests;
|
|
78
|
+
return failureRate >= this.config.failureThreshold;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Transition to CLOSED state (recovered)
|
|
82
|
+
*/
|
|
83
|
+
transitionToClosed() {
|
|
84
|
+
this.state = CircuitBreakerState.CLOSED;
|
|
85
|
+
this.successCount = 0;
|
|
86
|
+
this.failureCount = 0;
|
|
87
|
+
this.halfOpenAttempts = 0;
|
|
88
|
+
this.lastRecoveryTime = new Date();
|
|
89
|
+
if (this.resetTimer) {
|
|
90
|
+
clearTimeout(this.resetTimer);
|
|
91
|
+
this.resetTimer = undefined;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Transition to OPEN state (failing)
|
|
96
|
+
*/
|
|
97
|
+
transitionToOpen() {
|
|
98
|
+
this.state = CircuitBreakerState.OPEN;
|
|
99
|
+
this.successCount = 0;
|
|
100
|
+
this.failureCount = 0;
|
|
101
|
+
this.halfOpenAttempts = 0;
|
|
102
|
+
// Schedule recovery attempt
|
|
103
|
+
if (this.resetTimer) {
|
|
104
|
+
clearTimeout(this.resetTimer);
|
|
105
|
+
}
|
|
106
|
+
this.resetTimer = setTimeout(() => {
|
|
107
|
+
this.logger.info(`${this.name}: attempting recovery (OPEN -> HALF_OPEN)`);
|
|
108
|
+
this.state = CircuitBreakerState.HALF_OPEN;
|
|
109
|
+
this.halfOpenAttempts = 0;
|
|
110
|
+
}, this.config.resetTimeoutMs);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Check if the circuit allows operations
|
|
114
|
+
*/
|
|
115
|
+
canExecute() {
|
|
116
|
+
if (this.state === CircuitBreakerState.CLOSED) {
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
if (this.state === CircuitBreakerState.HALF_OPEN) {
|
|
120
|
+
return this.halfOpenAttempts < this.config.maxHalfOpenRequests;
|
|
121
|
+
}
|
|
122
|
+
// OPEN state
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Mark that we tried to execute in half-open state
|
|
127
|
+
*/
|
|
128
|
+
markHalfOpenAttempt() {
|
|
129
|
+
if (this.state === CircuitBreakerState.HALF_OPEN) {
|
|
130
|
+
this.halfOpenAttempts++;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Get current state
|
|
135
|
+
*/
|
|
136
|
+
getState() {
|
|
137
|
+
return this.state;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Get current failure rate (0-1)
|
|
141
|
+
*/
|
|
142
|
+
getFailureRate() {
|
|
143
|
+
const total = this.successCount + this.failureCount;
|
|
144
|
+
return total === 0 ? 0 : this.failureCount / total;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Get statistics
|
|
148
|
+
*/
|
|
149
|
+
getStats() {
|
|
150
|
+
const totalRequests = this.successCount + this.failureCount;
|
|
151
|
+
return {
|
|
152
|
+
state: this.state,
|
|
153
|
+
successCount: this.successCount,
|
|
154
|
+
failureCount: this.failureCount,
|
|
155
|
+
successRate: totalRequests === 0 ? 1 : this.successCount / totalRequests,
|
|
156
|
+
totalRequests,
|
|
157
|
+
lastFailureTime: this.lastFailureTime,
|
|
158
|
+
lastRecoveryTime: this.lastRecoveryTime,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Reset circuit breaker (for testing)
|
|
163
|
+
*/
|
|
164
|
+
reset() {
|
|
165
|
+
this.logger.debug(`${this.name}: reset`);
|
|
166
|
+
this.state = CircuitBreakerState.CLOSED;
|
|
167
|
+
this.successCount = 0;
|
|
168
|
+
this.failureCount = 0;
|
|
169
|
+
this.halfOpenAttempts = 0;
|
|
170
|
+
this.lastFailureTime = undefined;
|
|
171
|
+
this.lastRecoveryTime = undefined;
|
|
172
|
+
if (this.resetTimer) {
|
|
173
|
+
clearTimeout(this.resetTimer);
|
|
174
|
+
this.resetTimer = undefined;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Cleanup
|
|
179
|
+
*/
|
|
180
|
+
cleanup() {
|
|
181
|
+
if (this.resetTimer) {
|
|
182
|
+
clearTimeout(this.resetTimer);
|
|
183
|
+
this.resetTimer = undefined;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=circuit-breaker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circuit-breaker.js","sourceRoot":"","sources":["../../src/utils/circuit-breaker.ts"],"names":[],"mappings":"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"}
|