@typecad/hal 1.0.0-alpha.6 → 1.0.0-alpha.7

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/src/ble.ts ADDED
@@ -0,0 +1,209 @@
1
+ import {
2
+ bleServerBegin,
3
+ bleAdvertiseStart,
4
+ bleAdvertiseStop,
5
+ bleAddService,
6
+ bleAddChar,
7
+ bleOnRead,
8
+ bleOnWrite,
9
+ bleOnConnect,
10
+ bleOnDisconnect,
11
+ bleNotify,
12
+ bleIsConnected,
13
+ bleClientCount,
14
+ bleSetName,
15
+ bleUntilConnected,
16
+ bleUntilConnectedStart,
17
+ bleSetTxPower,
18
+ bleStatus,
19
+ } from './emit.js';
20
+ import { callback } from './callback.js';
21
+
22
+ /** Characteristic value encoding — drives both TS callback types and C++ marshalling. */
23
+ export enum BleValueType {
24
+ Uint8 = 'uint8',
25
+ Uint16 = 'uint16',
26
+ Uint32 = 'uint32',
27
+ Int8 = 'int8',
28
+ Int16 = 'int16',
29
+ Int32 = 'int32',
30
+ Float32 = 'float32',
31
+ Utf8 = 'utf8',
32
+ Boolean = 'boolean',
33
+ Bytes = 'bytes',
34
+ }
35
+
36
+ /** GATT characteristic permission flags. Combine with `|`. */
37
+ export enum BlePerm {
38
+ Read = 1,
39
+ Write = 2,
40
+ Notify = 4,
41
+ }
42
+
43
+ /** BLE peripheral status (mirrored by the runtime shim). */
44
+ export enum BleStatus {
45
+ Idle = 0,
46
+ Initializing = 1,
47
+ Advertising = 2,
48
+ Connected = 3,
49
+ Error = 4,
50
+ }
51
+
52
+ export enum BleAdvertisingMode {
53
+ Connectable = 'connectable',
54
+ NonConnectable = 'non_connectable',
55
+ }
56
+
57
+ /** A well-known GATT characteristic entry in the catalog. */
58
+ export interface GattCharacteristicDef {
59
+ readonly uuid: string;
60
+ readonly type: BleValueType;
61
+ readonly read?: boolean;
62
+ readonly write?: boolean;
63
+ readonly notify?: boolean;
64
+ }
65
+
66
+ /**
67
+ * Standard GATT services/characteristics. Autocomplete walks the hierarchy:
68
+ * GATT.ENVIRONMENTAL. -> TEMPERATURE, HUMIDITY, ...
69
+ * Pass the .uuid, .type, and computed perms to BleServer.characteristic().
70
+ */
71
+ export const GATT = {
72
+ DEVICE_INFO: {
73
+ MANUFACTURER_NAME: { uuid: '2A29', type: BleValueType.Utf8, read: true },
74
+ MODEL_NUMBER: { uuid: '2A24', type: BleValueType.Utf8, read: true },
75
+ FIRMWARE_REVISION: { uuid: '2A26', type: BleValueType.Utf8, read: true },
76
+ },
77
+ ENVIRONMENTAL: {
78
+ TEMPERATURE: { uuid: '2A6E', type: BleValueType.Int16, read: true, notify: true },
79
+ HUMIDITY: { uuid: '2A6F', type: BleValueType.Uint16, read: true, notify: true },
80
+ PRESSURE: { uuid: '2A6D', type: BleValueType.Uint32, read: true, notify: true },
81
+ },
82
+ BATTERY: {
83
+ LEVEL: { uuid: '2A19', type: BleValueType.Uint8, read: true, notify: true },
84
+ },
85
+ } as const;
86
+
87
+ /** The value passed to/from callbacks — narrowed per characteristic by type. */
88
+ export type CharValue = number | string | boolean | Uint8Array;
89
+
90
+ /**
91
+ * BLE GATT peripheral control, lowered to native ESP-IDF NimBLE
92
+ * (`nimble_host` / `ble_gap` / `ble_gatts`) by framework-esp32.
93
+ *
94
+ * No `include()` calls here — NimBLE headers are framework-owned and added via
95
+ * forcedIncludes when the program uses ble.* ops.
96
+ *
97
+ * Transpiler note: method bodies pass parameters directly into semantic calls
98
+ * (no local consts / module counters) so the resolver can statically track every
99
+ * argument. The characteristic index is carried through the chain via
100
+ * `this._charCount` fieldValues, mirroring how HttpRequest carries _method/_url.
101
+ */
102
+ export class BleClass {
103
+ static readonly __instance_name = "Ble";
104
+
105
+ /** Begin building a GATT server with the given advertised device name. */
106
+ server(name: string): BleServer {
107
+ bleSetName(name);
108
+ return new BleServer(name, 0, 1);
109
+ }
110
+
111
+ /** Initialize NimBLE, register services, and start advertising. */
112
+ begin(): void {
113
+ bleServerBegin("TypeCAD");
114
+ bleAdvertiseStart();
115
+ }
116
+
117
+ advertise(): void { bleAdvertiseStart(); }
118
+ stopAdvertising(): void { bleAdvertiseStop(); }
119
+
120
+ /** Blocking at top level; cooperatively awaitable inside async functions. */
121
+ untilConnected(timeoutMs: number = 0): Promise<boolean> {
122
+ bleUntilConnected(timeoutMs);
123
+ return Promise.resolve(false);
124
+ }
125
+
126
+ untilConnectedStart(): void { bleUntilConnectedStart(); }
127
+ isConnected(): boolean { return bleIsConnected(); }
128
+ status(): BleStatus { return bleStatus() as BleStatus; }
129
+ clientCount(): number { return bleClientCount(); }
130
+ txPower(dbm: number): this { bleSetTxPower(dbm); return this; }
131
+ notify(index: number, value: number): void { bleNotify(index, value); }
132
+ }
133
+
134
+ /**
135
+ * Fluent GATT server builder. Returned by `Ble.server()`.
136
+ *
137
+ * Single-class fluent chain (like HttpRequest): characteristic() returns `this`,
138
+ * so onRead/onWrite/onSubscribe chain directly. The _charCount field tracks
139
+ * which characteristic slot the callbacks attach to.
140
+ *
141
+ * Field tracking (read by the transpiler resolver via ctor field assignment):
142
+ * _name — advertised device name
143
+ * _charCount — current characteristic index (the last characteristic() target)
144
+ * _svcCount — current service index
145
+ */
146
+ export class BleServer {
147
+ private _name: string;
148
+ private _charCount: number;
149
+ private _lastChar: number;
150
+ private _svcCount: number;
151
+
152
+ constructor(name: string, charCount: number, svcCount: number) {
153
+ this._name = name;
154
+ this._charCount = charCount;
155
+ this._lastChar = charCount;
156
+ this._svcCount = svcCount;
157
+ }
158
+
159
+ /** Add a characteristic by UUID, value type, and permissions.
160
+ * Combine permissions with `|`: `BlePerm.Read | BlePerm.Notify`.
161
+ * Returns this for chaining. */
162
+ characteristic(uuid: string, type: BleValueType, perms: number): this {
163
+ bleAddChar(this._charCount, uuid, type, perms, this._svcCount);
164
+ return this;
165
+ }
166
+
167
+ /** Begin a new service grouping. Subsequent characteristics attach to it. */
168
+ service(uuid: string): this {
169
+ bleAddService(uuid);
170
+ return this;
171
+ }
172
+
173
+ /** Register a read handler for the most recently added characteristic. */
174
+ onRead(handler: () => CharValue): this {
175
+ bleOnRead(this._lastChar, callback(handler));
176
+ return this;
177
+ }
178
+
179
+ /** Register a write handler for the most recently added characteristic. */
180
+ onWrite(handler: (value: number) => void): this {
181
+ bleOnWrite(this._lastChar, callback(handler));
182
+ return this;
183
+ }
184
+
185
+ /** Register a connect handler (called when a central connects). */
186
+ onConnect(handler: () => void): this {
187
+ bleOnConnect(callback(handler));
188
+ return this;
189
+ }
190
+
191
+ /** Register a disconnect handler (called when a central disconnects). */
192
+ onDisconnect(handler: () => void): this {
193
+ bleOnDisconnect(callback(handler));
194
+ return this;
195
+ }
196
+
197
+ /** Push a new value to subscribed clients on the most recently added characteristic. */
198
+ notify(value: number): void {
199
+ bleNotify(this._lastChar, value);
200
+ }
201
+
202
+ /** Initialize NimBLE, register services, and start advertising. */
203
+ begin(): void {
204
+ bleServerBegin(this._name);
205
+ bleAdvertiseStart();
206
+ }
207
+ }
208
+
209
+ export const Ble = new BleClass();
package/src/emit.ts CHANGED
@@ -30,6 +30,49 @@ export function gpioSetMode(pin: number | string, mode: string): void {}
30
30
  /** Write PWM duty cycle to a pin. */
31
31
  export function pwmWrite(pin: number | string, duty: number): void {}
32
32
 
33
+ // ---------------------------------------------------------------------------
34
+ // RMT — Remote Control Transceiver (addressable LEDs, IR, raw digital waveforms)
35
+ // ---------------------------------------------------------------------------
36
+ // rmtTxInit/rmtRxInit are POSITIONAL semantic primitives — the ergonomic
37
+ // opts-object form lives in hal/rmt.ts (which destructures and forwards). The
38
+ // resolver collapses object literals, so HALOpIR fields must be scalars; the
39
+ // rmt.ts wrapper bridges the ergonomic API to these positional calls.
40
+ //
41
+ // Pin params accept Pin | number | string so callers can pass a board alias
42
+ // like LED (a Pin object) directly; the transpiler resolves it to its number.
43
+ import type { Pin } from './gpio.js';
44
+ type RmtPin = Pin | number | string;
45
+
46
+ /** Positional semantic primitive. Args: pin, resolutionHz, bit0Hi, bit0Lo,
47
+ * bit1Hi, bit1Lo, msbFirst, queueDepth. Use rmtTxInit() from hal/rmt.ts. */
48
+ export function rmtTxInit(
49
+ pin: RmtPin,
50
+ resolutionHz: number,
51
+ bit0Hi: number, bit0Lo: number, bit1Hi: number, bit1Lo: number,
52
+ msbFirst: boolean, queueDepth: number,
53
+ ): void {}
54
+ /** Write bytes via the channel's bytes-encoder (timings fixed at init). */
55
+ export function rmtTxWriteBytes(pin: RmtPin, bytes: number[] | Uint8Array): void {}
56
+ /** Write raw RMT symbols — arbitrary [hiTicks, loTicks] pairs. */
57
+ export function rmtTxWriteSymbols(pin: RmtPin, symbols: [number, number][]): void {}
58
+ /** Block until the queued TX completes. */
59
+ export function rmtTxWaitDone(pin: RmtPin, timeoutMs?: number): void {}
60
+ /** Tear down the TX channel and release its slot. */
61
+ export function rmtTxDeinit(pin: RmtPin): void {}
62
+
63
+ /** Positional semantic primitive — use rmtRxInit() from hal/rmt.ts. */
64
+ export function rmtRxInit(pin: RmtPin, resolutionHz: number): void {}
65
+ /** Register a callback-by-name invoked when an RX burst completes. */
66
+ export function rmtRxOnReceived(pin: RmtPin, handler: string): void {}
67
+ /** Start receiving. */
68
+ export function rmtRxStart(pin: RmtPin): void {}
69
+ /** Stop receiving. */
70
+ export function rmtRxStop(pin: RmtPin): void {}
71
+ /** Blocking read — returns flattened symbols [d0,l0,d1,l1,…] in ticks. */
72
+ export function rmtRxRead(pin: RmtPin, maxCount: number): number[] { return []; }
73
+ /** Tear down the RX channel and release its slot. */
74
+ export function rmtRxDeinit(pin: RmtPin): void {}
75
+
33
76
  // ---------------------------------------------------------------------------
34
77
  // ADC — analog-to-digital conversion
35
78
  // ---------------------------------------------------------------------------
@@ -218,6 +261,104 @@ export function powerDeepSleep(ms: number): void {}
218
261
  export function powerLightSleep(): void {}
219
262
  /** Set the CPU frequency (MHz). */
220
263
  export function powerSetCpuFrequency(mhz: number): void {}
264
+ /** Enter deep sleep until `pin` reaches `level` (pin wakeup). Architecture-aware:
265
+ * ext0 on Xtensa (RTC pins), gpio-wakeup on RISC-V. */
266
+ export function powerDeepSleepPin(pin: number, level: number): void {}
267
+
268
+ // ---------------------------------------------------------------------------
269
+ // Preferences (NVS-backed key/value store)
270
+ // ---------------------------------------------------------------------------
271
+
272
+ export function preferencesBegin(namespace: string, readOnly: boolean): void {}
273
+ export function preferencesEnd(): void {}
274
+ export function preferencesClear(): void {}
275
+ export function preferencesRemove(key: string): void {}
276
+ export function preferencesPutInt(key: string, value: number): void {}
277
+ export function preferencesGetInt(key: string, defaultValue: number): number { return 0; }
278
+ export function preferencesPutUInt(key: string, value: number): void {}
279
+ export function preferencesGetUInt(key: string, defaultValue: number): number { return 0; }
280
+ export function preferencesPutBool(key: string, value: boolean): void {}
281
+ export function preferencesGetBool(key: string, defaultValue: boolean): boolean { return false; }
282
+ export function preferencesPutFloat(key: string, value: number): void {}
283
+ export function preferencesGetFloat(key: string, defaultValue: number): number { return 0; }
284
+ export function preferencesPutString(key: string, value: string): void {}
285
+ export function preferencesGetString(key: string, defaultValue: string): string { return ""; }
286
+
287
+ export function wifiConnect(ssid: string, password?: string, timeoutMs?: number): boolean { return false; }
288
+ export function wifiConnectStart(ssid: string, password?: string): void {}
289
+ export function wifiDisconnect(): void {}
290
+ export function wifiStatus(): number { return 0; }
291
+ export function wifiIsConnected(): boolean { return false; }
292
+ export function wifiLocalIp(): string { return ""; }
293
+ export function wifiRssi(): number { return 0; }
294
+ export function wifiMac(): string { return ""; }
295
+ export function wifiSetHostname(name: string): void {}
296
+ export function wifiSetStaticIp(ip: string, gateway: string, subnet: string, dns?: string): void {}
297
+ export function wifiSetAutoReconnect(enabled: boolean): void {}
298
+ export function wifiSetPowerSave(mode: string): void {}
299
+ export function wifiSetTxPower(dbm: number): void {}
300
+ export function wifiOnEvent(event: string, handler: string): void {}
301
+ export function wifiApStart(ssid: string, password?: string, channel?: number, hidden?: boolean, maxClients?: number): boolean { return false; }
302
+ export function wifiApStop(): void {}
303
+ export function wifiApClientCount(): number { return 0; }
304
+ export function wifiApIp(): string { return ""; }
305
+ export function wifiApSetChannel(channel: number): void {}
306
+ export function wifiApSetHidden(hidden: boolean): void {}
307
+ export function wifiApSetMaxClients(maxClients: number): void {}
308
+ export function wifiScan(): number { return 0; }
309
+ export function wifiScanStart(): void {}
310
+ export function wifiScanCount(): number { return 0; }
311
+ export function wifiScanSsid(index: number): string { return ""; }
312
+ export function wifiScanRssi(index: number): number { return 0; }
313
+ export function wifiScanEncryption(index: number): number { return 0; }
314
+ export function wifiScanChannel(index: number): number { return 0; }
315
+ export function wifiSaveCredentials(ssid: string, password: string): void {}
316
+ export function wifiConnectSaved(timeoutMs?: number): boolean { return false; }
317
+ export function wifiClearCredentials(): void {}
318
+ export function wifiWaitConnected(timeoutMs?: number): boolean { return false; }
319
+ export function wifiWaitDisconnected(): void {}
320
+
321
+ // ---------------------------------------------------------------------------
322
+ // HTTP client
323
+ // ---------------------------------------------------------------------------
324
+
325
+ export function httpBegin(method: string, url: string): void {}
326
+ export function httpReset(): void {}
327
+ export function httpSetHeader(name: string, value: string): void {}
328
+ export function httpSetTimeout(ms: number): void {}
329
+ export function httpSetMaxBody(bytes: number): void {}
330
+ export function httpSetBody(data: string, json?: boolean): void {}
331
+ export function httpSetInsecure(): void {}
332
+ export function httpSetCaCert(pem: string): void {}
333
+ export function httpSend(): boolean { return false; }
334
+ export function httpSendStart(): void {}
335
+ export function httpStatus(): number { return 0; }
336
+ export function httpOk(): boolean { return false; }
337
+ export function httpBody(): string { return ""; }
338
+ export function httpContentLength(): number { return 0; }
339
+ export function httpResponseHeader(name: string): string { return ""; }
340
+
341
+ // ---------------------------------------------------------------------------
342
+ // BLE (NimBLE GATT peripheral)
343
+ // ---------------------------------------------------------------------------
344
+
345
+ export function bleServerBegin(name: string): void {}
346
+ export function bleAdvertiseStart(): void {}
347
+ export function bleAdvertiseStop(): void {}
348
+ export function bleAddService(uuid: string): void {}
349
+ export function bleAddChar(index: number, uuid: string, type: string, perms: number, svcIndex: number): void {}
350
+ export function bleOnRead(index: number, handler: string): void {}
351
+ export function bleOnWrite(index: number, handler: string): void {}
352
+ export function bleOnConnect(handler: string): void {}
353
+ export function bleOnDisconnect(handler: string): void {}
354
+ export function bleNotify(index: number, value: number | string): void {}
355
+ export function bleIsConnected(): boolean { return false; }
356
+ export function bleClientCount(): number { return 0; }
357
+ export function bleSetName(name: string): void {}
358
+ export function bleUntilConnected(timeoutMs?: number): boolean { return false; }
359
+ export function bleUntilConnectedStart(): void {}
360
+ export function bleSetTxPower(dbm: number): void {}
361
+ export function bleStatus(): number { return 0; }
221
362
 
222
363
  // ---------------------------------------------------------------------------
223
364
  // Raw C++ escape hatch
@@ -225,3 +366,20 @@ export function powerSetCpuFrequency(mhz: number): void {}
225
366
 
226
367
  /** Emit raw C++ code (escape hatch for unsupported operations). */
227
368
  export function rawCpp(code: string): void {}
369
+
370
+ /**
371
+ * Emit raw C++ in expression context. Use when an IDF macro or constructor
372
+ * must produce a value (e.g. `WIFI_INIT_CONFIG_DEFAULT()` expands to a struct
373
+ * initializer; there's no TS-side way to construct it). The type parameter
374
+ * is purely a TS hint — the transpiler doesn't check it; it just emits the
375
+ * raw text in expression position.
376
+ *
377
+ * const cfg = rawCpp<wifi_init_config_t>('WIFI_INIT_CONFIG_DEFAULT()');
378
+ *
379
+ * lowers to:
380
+ *
381
+ * wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
382
+ */
383
+ export function rawCppExpr<T>(code: string): T {
384
+ return undefined as unknown as T;
385
+ }
package/src/http.ts ADDED
@@ -0,0 +1,144 @@
1
+ import {
2
+ httpBegin,
3
+ httpReset,
4
+ httpSetHeader,
5
+ httpSetTimeout,
6
+ httpSetMaxBody,
7
+ httpSetBody,
8
+ httpSetInsecure,
9
+ httpSetCaCert,
10
+ httpSend,
11
+ httpStatus,
12
+ httpOk,
13
+ httpBody,
14
+ httpContentLength,
15
+ httpResponseHeader,
16
+ } from './emit.js';
17
+
18
+ export enum HttpMethod {
19
+ GET = 0,
20
+ POST = 1,
21
+ PUT = 2,
22
+ DELETE = 3,
23
+ HEAD = 4,
24
+ PATCH = 5,
25
+ }
26
+
27
+ /**
28
+ * Fluent HTTP/S request builder, lowered to native ESP-IDF
29
+ * `esp_http_client` by framework-esp32 (TLS via esp-tls / mbedTLS bundle).
30
+ * Response fields are read from this object after send() — mirrors
31
+ * `await WiFi.connect(); WiFi.localIP()`.
32
+ *
33
+ * No `include()` calls here — ESP-IDF headers are framework-owned and added
34
+ * via forcedIncludes when the program uses http.* ops.
35
+ */
36
+ export class HttpRequest {
37
+ private _method: string;
38
+ private _url: string;
39
+
40
+ constructor(method: string, url: string) {
41
+ this._method = method;
42
+ this._url = url;
43
+ }
44
+
45
+ header(name: string, value: string): this {
46
+ httpSetHeader(name, value);
47
+ return this;
48
+ }
49
+
50
+ timeout(ms: number): this {
51
+ httpSetTimeout(ms);
52
+ return this;
53
+ }
54
+
55
+ maxBody(bytes: number): this {
56
+ httpSetMaxBody(bytes);
57
+ return this;
58
+ }
59
+
60
+ body(data: string): this {
61
+ httpSetBody(data, false);
62
+ return this;
63
+ }
64
+
65
+ jsonBody(json: string): this {
66
+ httpSetBody(json, true);
67
+ return this;
68
+ }
69
+
70
+ /** Skip TLS certificate verification (development only). */
71
+ insecure(): this {
72
+ httpSetInsecure();
73
+ return this;
74
+ }
75
+
76
+ caCert(pem: string): this {
77
+ httpSetCaCert(pem);
78
+ return this;
79
+ }
80
+
81
+ /** Blocking at top level; cooperatively awaitable inside async functions. */
82
+ send(): Promise<boolean> {
83
+ httpBegin(this._method, this._url);
84
+ httpSend();
85
+ return Promise.resolve(false);
86
+ }
87
+
88
+ status(): number {
89
+ return httpStatus();
90
+ }
91
+
92
+ ok(): boolean {
93
+ return httpOk();
94
+ }
95
+
96
+ /** Response body as a C string (valid until the next request). */
97
+ text(): string {
98
+ return httpBody();
99
+ }
100
+
101
+ contentLength(): number {
102
+ return httpContentLength();
103
+ }
104
+
105
+ responseHeader(name: string): string {
106
+ return httpResponseHeader(name);
107
+ }
108
+ }
109
+
110
+ export class HttpClass {
111
+ static readonly __instance_name = "Http";
112
+
113
+ get(url: string): HttpRequest {
114
+ httpReset();
115
+ return new HttpRequest("GET", url);
116
+ }
117
+
118
+ post(url: string): HttpRequest {
119
+ httpReset();
120
+ return new HttpRequest("POST", url);
121
+ }
122
+
123
+ put(url: string): HttpRequest {
124
+ httpReset();
125
+ return new HttpRequest("PUT", url);
126
+ }
127
+
128
+ del(url: string): HttpRequest {
129
+ httpReset();
130
+ return new HttpRequest("DELETE", url);
131
+ }
132
+
133
+ head(url: string): HttpRequest {
134
+ httpReset();
135
+ return new HttpRequest("HEAD", url);
136
+ }
137
+
138
+ patch(url: string): HttpRequest {
139
+ httpReset();
140
+ return new HttpRequest("PATCH", url);
141
+ }
142
+ }
143
+
144
+ export const Http = new HttpClass();
package/src/index.ts CHANGED
@@ -19,7 +19,7 @@ export type { SPIBitOrder, SPIMode, SPISettings } from './types.js';
19
19
  export { include } from './include.js';
20
20
  export { board } from './board.js';
21
21
  export { callback } from './callback.js';
22
- export { rawCpp, boardResolve } from './emit.js';
22
+ export { rawCpp, rawCppExpr, boardResolve } from './emit.js';
23
23
  export { HIGH, LOW, OUTPUT, INPUT, INPUT_PULLUP, INPUT_PULLDOWN, OUTPUT_OPEN_DRAIN, ANALOG, LED_BUILTIN, LSBFIRST, MSBFIRST, WDTO_15MS, WDTO_30MS, WDTO_60MS, WDTO_120MS, WDTO_250MS, WDTO_500MS, WDTO_1S, WDTO_2S, WDTO_4S, WDTO_8S } from './constants.js';
24
24
  export { delay, millis, micros, delayMicroseconds, map, constrain, TimingClass, Timing } from './timing.js';
25
25
  export { freeHeap, setInterval, setTimeout, clearInterval, clearTimeout } from './timing.js';
@@ -46,3 +46,11 @@ export { HardwareTimer, Timer0, Timer1, Timer2 } from './timer.js';
46
46
  export { FSClass, FS } from './fs.js';
47
47
  export { PowerClass, Power } from './power.js';
48
48
  export { AsyncClass, Async } from './async.js';
49
+ export { WiFiClass, WiFi, WiFiStatus, WiFiEncryption } from './wifi.js';
50
+ export { HttpClass, Http, HttpRequest, HttpMethod } from './http.js';
51
+ export {
52
+ BleClass, Ble, BleServer,
53
+ BleValueType, BlePerm, BleStatus, BleAdvertisingMode, GATT,
54
+ } from './ble.js';
55
+ export type { GattCharacteristicDef, CharValue } from './ble.js';
56
+ export { RmtChannel } from './rmt.js';
package/src/power.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { powerDeepSleep, powerLightSleep, powerSetCpuFrequency } from './emit.js';
1
+ import { powerDeepSleep, powerLightSleep, powerSetCpuFrequency, powerDeepSleepPin } from './emit.js';
2
2
 
3
3
  /**
4
4
  * PowerClass provides control over MCU power states and clock frequencies.
@@ -14,6 +14,16 @@ export class PowerClass {
14
14
  powerDeepSleep(ms);
15
15
  }
16
16
 
17
+ /** Enter deep sleep until `pin` reaches `level` (0 = low, 1 = high).
18
+ *
19
+ * Lowers to ext0 wakeup (Xtensa ESP32/S3, RTC pins only) or the gpio-wakeup
20
+ * variant (RISC-V C3/C6) depending on the target. `pin` must be RTC-capable;
21
+ * the framework flags non-RTC pins at compile time. Wakeup resets the chip,
22
+ * so this call never returns. */
23
+ deepSleepPin(pin: number, level: 0 | 1): void {
24
+ powerDeepSleepPin(pin, level);
25
+ }
26
+
17
27
  lightSleep(): void {
18
28
  powerLightSleep();
19
29
  }
@@ -1,57 +1,86 @@
1
- import { rawCpp } from './emit.js';
1
+ import {
2
+ preferencesBegin,
3
+ preferencesEnd,
4
+ preferencesClear,
5
+ preferencesRemove,
6
+ preferencesPutInt,
7
+ preferencesGetInt,
8
+ preferencesPutUInt,
9
+ preferencesGetUInt,
10
+ preferencesPutBool,
11
+ preferencesGetBool,
12
+ preferencesPutFloat,
13
+ preferencesGetFloat,
14
+ preferencesPutString,
15
+ preferencesGetString,
16
+ } from './emit.js';
2
17
 
18
+ /**
19
+ * Preferences — a persistent key/value store, lowered to native NVS
20
+ * (nvs_flash / nvs_open / nvs_set_* / nvs_get_*) by framework-esp32.
21
+ *
22
+ * No include() calls here — NVS headers are framework-owned and added via
23
+ * forcedIncludes when the program uses preferences.* ops. Method bodies pass
24
+ * parameters directly into semantic calls so the resolver can statically track
25
+ * every argument (matching the WiFi/HTTP HAL pattern).
26
+ */
3
27
  export class PreferencesClass {
4
28
  static readonly __instance_name = "Preferences";
5
- // NOTE: no __includes here. The transpiler emits singleton __includes on
6
- // every architecture with no filtering, and <Preferences.h> is ESP32-only —
7
- // adding it would break AVR builds. The class is ESP32-only by convention.
8
29
 
9
30
  begin(name: string, readOnly: boolean = false): void {
10
- rawCpp(`Preferences.begin(${name}.c_str(), ${readOnly});`);
31
+ preferencesBegin(name, readOnly);
11
32
  }
33
+
12
34
  end(): void {
13
- rawCpp(`Preferences.end();`);
35
+ preferencesEnd();
14
36
  }
37
+
15
38
  clear(): void {
16
- rawCpp(`Preferences.clear();`);
39
+ preferencesClear();
17
40
  }
41
+
18
42
  remove(key: string): void {
19
- rawCpp(`Preferences.remove(${key}.c_str());`);
43
+ preferencesRemove(key);
20
44
  }
45
+
21
46
  putInt(key: string, value: number): void {
22
- rawCpp(`Preferences.putInt(${key}.c_str(), ${value});`);
47
+ preferencesPutInt(key, value);
23
48
  }
49
+
24
50
  getInt(key: string, defaultValue: number = 0): number {
25
- rawCpp(`return Preferences.getInt(${key}.c_str(), ${defaultValue});`);
26
- return 0;
51
+ return preferencesGetInt(key, defaultValue);
27
52
  }
53
+
28
54
  putUInt(key: string, value: number): void {
29
- rawCpp(`Preferences.putUInt(${key}.c_str(), ${value});`);
55
+ preferencesPutUInt(key, value);
30
56
  }
57
+
31
58
  getUInt(key: string, defaultValue: number = 0): number {
32
- rawCpp(`return Preferences.getUInt(${key}.c_str(), ${defaultValue});`);
33
- return 0;
34
- }
35
- putFloat(key: string, value: number): void {
36
- rawCpp(`Preferences.putFloat(${key}.c_str(), ${value});`);
37
- }
38
- getFloat(key: string, defaultValue: number = 0): number {
39
- rawCpp(`return Preferences.getFloat(${key}.c_str(), ${defaultValue});`);
40
- return 0;
59
+ return preferencesGetUInt(key, defaultValue);
41
60
  }
61
+
42
62
  putBool(key: string, value: boolean): void {
43
- rawCpp(`Preferences.putBool(${key}.c_str(), ${value});`);
63
+ preferencesPutBool(key, value);
44
64
  }
65
+
45
66
  getBool(key: string, defaultValue: boolean = false): boolean {
46
- rawCpp(`return Preferences.getBool(${key}.c_str(), ${defaultValue});`);
47
- return false;
67
+ return preferencesGetBool(key, defaultValue);
68
+ }
69
+
70
+ putFloat(key: string, value: number): void {
71
+ preferencesPutFloat(key, value);
48
72
  }
73
+
74
+ getFloat(key: string, defaultValue: number = 0): number {
75
+ return preferencesGetFloat(key, defaultValue);
76
+ }
77
+
49
78
  putString(key: string, value: string): void {
50
- rawCpp(`Preferences.putString(${key}.c_str(), ${value}.c_str());`);
79
+ preferencesPutString(key, value);
51
80
  }
81
+
52
82
  getString(key: string, defaultValue: string = ""): string {
53
- rawCpp(`return Preferences.getString(${key}.c_str(), ${defaultValue}.c_str());`);
54
- return "";
83
+ return preferencesGetString(key, defaultValue);
55
84
  }
56
85
  }
57
86